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#define DEBUG_SUBSYSTEM S_MGC
39#define D_MGC D_CONFIG
40
41#include <linux/module.h>
42
43#include <lprocfs_status.h>
44#include <lustre_dlm.h>
45#include <lustre_disk.h>
46#include <lustre_log.h>
47#include <lustre_swab.h>
48#include <obd_class.h>
49
50#include "mgc_internal.h"
51
52static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id,
53 int type)
54{
55 __u64 resname = 0;
56
57 if (len > sizeof(resname)) {
58 CERROR("name too long: %s\n", name);
59 return -EINVAL;
60 }
61 if (len <= 0) {
62 CERROR("missing name: %s\n", name);
63 return -EINVAL;
64 }
65 memcpy(&resname, name, len);
66
67
68 memset(res_id, 0, sizeof(*res_id));
69 res_id->name[0] = cpu_to_le64(resname);
70
71 switch (type) {
72 case CONFIG_T_CONFIG:
73 case CONFIG_T_SPTLRPC:
74 resname = 0;
75 break;
76 case CONFIG_T_RECOVER:
77 case CONFIG_T_PARAMS:
78 resname = type;
79 break;
80 default:
81 LBUG();
82 }
83 res_id->name[1] = cpu_to_le64(resname);
84 CDEBUG(D_MGC, "log %s to resid %#llx/%#llx (%.8s)\n", name,
85 res_id->name[0], res_id->name[1], (char *)&res_id->name[0]);
86 return 0;
87}
88
89int mgc_fsname2resid(char *fsname, struct ldlm_res_id *res_id, int type)
90{
91
92
93
94 return mgc_name2resid(fsname, strlen(fsname), res_id, type);
95}
96EXPORT_SYMBOL(mgc_fsname2resid);
97
98static int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id, int type)
99{
100 char *name_end;
101 int len;
102
103
104
105
106
107 name_end = strrchr(logname, '-');
108 if (!name_end)
109 len = strlen(logname);
110 else
111 len = name_end - logname;
112 return mgc_name2resid(logname, len, res_id, type);
113}
114
115
116static LIST_HEAD(config_llog_list);
117static DEFINE_SPINLOCK(config_list_lock);
118
119
120static int config_log_get(struct config_llog_data *cld)
121{
122 atomic_inc(&cld->cld_refcount);
123 CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname,
124 atomic_read(&cld->cld_refcount));
125 return 0;
126}
127
128
129
130
131static void config_log_put(struct config_llog_data *cld)
132{
133 CDEBUG(D_INFO, "log %s refs %d\n", cld->cld_logname,
134 atomic_read(&cld->cld_refcount));
135 LASSERT(atomic_read(&cld->cld_refcount) > 0);
136
137
138 if (atomic_dec_and_lock(&cld->cld_refcount, &config_list_lock)) {
139 list_del(&cld->cld_list_chain);
140 spin_unlock(&config_list_lock);
141
142 CDEBUG(D_MGC, "dropping config log %s\n", cld->cld_logname);
143
144 if (cld->cld_recover)
145 config_log_put(cld->cld_recover);
146 if (cld->cld_params)
147 config_log_put(cld->cld_params);
148 if (cld->cld_sptlrpc)
149 config_log_put(cld->cld_sptlrpc);
150 if (cld_is_sptlrpc(cld))
151 sptlrpc_conf_log_stop(cld->cld_logname);
152
153 class_export_put(cld->cld_mgcexp);
154 kfree(cld);
155 }
156}
157
158
159static
160struct config_llog_data *config_log_find(char *logname,
161 struct config_llog_instance *cfg)
162{
163 struct config_llog_data *cld;
164 struct config_llog_data *found = NULL;
165 void *instance;
166
167 LASSERT(logname);
168
169 instance = cfg ? cfg->cfg_instance : NULL;
170 spin_lock(&config_list_lock);
171 list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
172
173 if (instance != cld->cld_cfg.cfg_instance)
174 continue;
175
176
177 if (strcmp(logname, cld->cld_logname) == 0) {
178 found = cld;
179 config_log_get(found);
180 break;
181 }
182 }
183 spin_unlock(&config_list_lock);
184 return found;
185}
186
187static
188struct config_llog_data *do_config_log_add(struct obd_device *obd,
189 char *logname,
190 int type,
191 struct config_llog_instance *cfg,
192 struct super_block *sb)
193{
194 struct config_llog_data *cld;
195 int rc;
196
197 CDEBUG(D_MGC, "do adding config log %s:%p\n", logname,
198 cfg ? cfg->cfg_instance : NULL);
199
200 cld = kzalloc(sizeof(*cld) + strlen(logname) + 1, GFP_NOFS);
201 if (!cld)
202 return ERR_PTR(-ENOMEM);
203
204 rc = mgc_logname2resid(logname, &cld->cld_resid, type);
205 if (rc) {
206 kfree(cld);
207 return ERR_PTR(rc);
208 }
209
210 strcpy(cld->cld_logname, logname);
211 if (cfg)
212 cld->cld_cfg = *cfg;
213 else
214 cld->cld_cfg.cfg_callback = class_config_llog_handler;
215 mutex_init(&cld->cld_lock);
216 cld->cld_cfg.cfg_last_idx = 0;
217 cld->cld_cfg.cfg_flags = 0;
218 cld->cld_cfg.cfg_sb = sb;
219 cld->cld_type = type;
220 atomic_set(&cld->cld_refcount, 1);
221
222
223 cld->cld_mgcexp = class_export_get(obd->obd_self_export);
224
225 if (cld_is_sptlrpc(cld)) {
226 sptlrpc_conf_log_start(logname);
227 cld->cld_cfg.cfg_obdname = obd->obd_name;
228 }
229
230 spin_lock(&config_list_lock);
231 list_add(&cld->cld_list_chain, &config_llog_list);
232 spin_unlock(&config_list_lock);
233
234 if (cld_is_sptlrpc(cld)) {
235 rc = mgc_process_log(obd, cld);
236 if (rc && rc != -ENOENT)
237 CERROR("failed processing sptlrpc log: %d\n", rc);
238 }
239
240 return cld;
241}
242
243static struct config_llog_data *
244config_recover_log_add(struct obd_device *obd, char *fsname,
245 struct config_llog_instance *cfg,
246 struct super_block *sb)
247{
248 struct config_llog_instance lcfg = *cfg;
249 struct config_llog_data *cld;
250 char logname[32];
251
252
253
254
255 LASSERT(strlen(fsname) < sizeof(logname) / 2);
256 strcpy(logname, fsname);
257 LASSERT(lcfg.cfg_instance);
258 strcat(logname, "-cliir");
259
260 cld = do_config_log_add(obd, logname, CONFIG_T_RECOVER, &lcfg, sb);
261 return cld;
262}
263
264static struct config_llog_data *
265config_params_log_add(struct obd_device *obd,
266 struct config_llog_instance *cfg, struct super_block *sb)
267{
268 struct config_llog_instance lcfg = *cfg;
269 struct config_llog_data *cld;
270
271 lcfg.cfg_instance = sb;
272
273 cld = do_config_log_add(obd, PARAMS_FILENAME, CONFIG_T_PARAMS,
274 &lcfg, sb);
275
276 return cld;
277}
278
279
280
281
282
283
284static struct config_llog_data *
285config_log_add(struct obd_device *obd, char *logname,
286 struct config_llog_instance *cfg, struct super_block *sb)
287{
288 struct lustre_sb_info *lsi = s2lsi(sb);
289 struct config_llog_data *cld;
290 struct config_llog_data *sptlrpc_cld;
291 struct config_llog_data *params_cld;
292 struct config_llog_data *recover_cld = NULL;
293 char seclogname[32];
294 char *ptr;
295 int rc;
296
297 CDEBUG(D_MGC, "adding config log %s:%p\n", logname, cfg->cfg_instance);
298
299
300
301
302
303 ptr = strrchr(logname, '-');
304 if (!ptr || ptr - logname > 8) {
305 CERROR("logname %s is too long\n", logname);
306 return ERR_PTR(-EINVAL);
307 }
308
309 memcpy(seclogname, logname, ptr - logname);
310 strcpy(seclogname + (ptr - logname), "-sptlrpc");
311
312 sptlrpc_cld = config_log_find(seclogname, NULL);
313 if (!sptlrpc_cld) {
314 sptlrpc_cld = do_config_log_add(obd, seclogname,
315 CONFIG_T_SPTLRPC, NULL, NULL);
316 if (IS_ERR(sptlrpc_cld)) {
317 CERROR("can't create sptlrpc log: %s\n", seclogname);
318 rc = PTR_ERR(sptlrpc_cld);
319 goto out_err;
320 }
321 }
322 params_cld = config_params_log_add(obd, cfg, sb);
323 if (IS_ERR(params_cld)) {
324 rc = PTR_ERR(params_cld);
325 CERROR("%s: can't create params log: rc = %d\n",
326 obd->obd_name, rc);
327 goto out_sptlrpc;
328 }
329
330 cld = do_config_log_add(obd, logname, CONFIG_T_CONFIG, cfg, sb);
331 if (IS_ERR(cld)) {
332 CERROR("can't create log: %s\n", logname);
333 rc = PTR_ERR(cld);
334 goto out_params;
335 }
336
337 LASSERT(lsi->lsi_lmd);
338 if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOIR)) {
339 ptr = strrchr(seclogname, '-');
340 if (ptr) {
341 *ptr = 0;
342 } else {
343 CERROR("%s: sptlrpc log name not correct, %s: rc = %d\n",
344 obd->obd_name, seclogname, -EINVAL);
345 rc = -EINVAL;
346 goto out_cld;
347 }
348 recover_cld = config_recover_log_add(obd, seclogname, cfg, sb);
349 if (IS_ERR(recover_cld)) {
350 rc = PTR_ERR(recover_cld);
351 goto out_cld;
352 }
353 }
354
355 mutex_lock(&cld->cld_lock);
356 cld->cld_recover = recover_cld;
357 cld->cld_params = params_cld;
358 cld->cld_sptlrpc = sptlrpc_cld;
359 mutex_unlock(&cld->cld_lock);
360
361 return cld;
362
363out_cld:
364 config_log_put(cld);
365
366out_params:
367 config_log_put(params_cld);
368
369out_sptlrpc:
370 config_log_put(sptlrpc_cld);
371
372out_err:
373 return ERR_PTR(rc);
374}
375
376static DEFINE_MUTEX(llog_process_lock);
377
378static inline void config_mark_cld_stop(struct config_llog_data *cld)
379{
380 mutex_lock(&cld->cld_lock);
381 spin_lock(&config_list_lock);
382 cld->cld_stopping = 1;
383 spin_unlock(&config_list_lock);
384 mutex_unlock(&cld->cld_lock);
385}
386
387
388
389static int config_log_end(char *logname, struct config_llog_instance *cfg)
390{
391 struct config_llog_data *cld;
392 struct config_llog_data *cld_sptlrpc = NULL;
393 struct config_llog_data *cld_params = NULL;
394 struct config_llog_data *cld_recover = NULL;
395 int rc = 0;
396
397 cld = config_log_find(logname, cfg);
398 if (!cld)
399 return -ENOENT;
400
401 mutex_lock(&cld->cld_lock);
402
403
404
405
406
407
408
409 if (unlikely(cld->cld_stopping)) {
410 mutex_unlock(&cld->cld_lock);
411
412 config_log_put(cld);
413 return rc;
414 }
415
416 spin_lock(&config_list_lock);
417 cld->cld_stopping = 1;
418 spin_unlock(&config_list_lock);
419
420 cld_recover = cld->cld_recover;
421 cld->cld_recover = NULL;
422
423 cld_params = cld->cld_params;
424 cld->cld_params = NULL;
425 cld_sptlrpc = cld->cld_sptlrpc;
426 cld->cld_sptlrpc = NULL;
427 mutex_unlock(&cld->cld_lock);
428
429 if (cld_recover) {
430 config_mark_cld_stop(cld_recover);
431 config_log_put(cld_recover);
432 }
433
434 if (cld_params) {
435 config_mark_cld_stop(cld_params);
436 config_log_put(cld_params);
437 }
438
439 if (cld_sptlrpc)
440 config_log_put(cld_sptlrpc);
441
442
443 config_log_put(cld);
444
445 config_log_put(cld);
446
447 CDEBUG(D_MGC, "end config log %s (%d)\n", logname ? logname : "client",
448 rc);
449 return rc;
450}
451
452int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data)
453{
454 struct obd_device *obd = data;
455 struct obd_import *imp;
456 struct obd_connect_data *ocd;
457 struct config_llog_data *cld;
458 int rc;
459
460 rc = lprocfs_climp_check(obd);
461 if (rc)
462 return rc;
463
464 imp = obd->u.cli.cl_import;
465 ocd = &imp->imp_connect_data;
466
467 seq_printf(m, "imperative_recovery: %s\n",
468 OCD_HAS_FLAG(ocd, IMP_RECOV) ? "ENABLED" : "DISABLED");
469 seq_printf(m, "client_state:\n");
470
471 spin_lock(&config_list_lock);
472 list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
473 if (!cld->cld_recover)
474 continue;
475 seq_printf(m, " - { client: %s, nidtbl_version: %u }\n",
476 cld->cld_logname,
477 cld->cld_recover->cld_cfg.cfg_last_idx);
478 }
479 spin_unlock(&config_list_lock);
480
481 up_read(&obd->u.cli.cl_sem);
482 return 0;
483}
484
485
486#define RQ_RUNNING 0x1
487#define RQ_NOW 0x2
488#define RQ_LATER 0x4
489#define RQ_STOP 0x8
490#define RQ_PRECLEANUP 0x10
491static int rq_state;
492static wait_queue_head_t rq_waitq;
493static DECLARE_COMPLETION(rq_exit);
494static DECLARE_COMPLETION(rq_start);
495
496static void do_requeue(struct config_llog_data *cld)
497{
498 LASSERT(atomic_read(&cld->cld_refcount) > 0);
499
500
501
502
503
504 down_read_nested(&cld->cld_mgcexp->exp_obd->u.cli.cl_sem,
505 OBD_CLI_SEM_MGC);
506
507 if (cld->cld_mgcexp->exp_obd->u.cli.cl_conn_count != 0) {
508 int rc;
509
510 CDEBUG(D_MGC, "updating log %s\n", cld->cld_logname);
511 rc = mgc_process_log(cld->cld_mgcexp->exp_obd, cld);
512 if (rc && rc != -ENOENT)
513 CERROR("failed processing log: %d\n", rc);
514 } else {
515 CDEBUG(D_MGC, "disconnecting, won't update log %s\n",
516 cld->cld_logname);
517 }
518 up_read(&cld->cld_mgcexp->exp_obd->u.cli.cl_sem);
519}
520
521
522
523
524
525#define MGC_TIMEOUT_MIN_SECONDS 5
526#define MGC_TIMEOUT_RAND_CENTISEC 500
527
528static int mgc_requeue_thread(void *data)
529{
530 bool first = true;
531
532 CDEBUG(D_MGC, "Starting requeue thread\n");
533
534
535 spin_lock(&config_list_lock);
536 rq_state |= RQ_RUNNING;
537 while (!(rq_state & RQ_STOP)) {
538 struct l_wait_info lwi;
539 struct config_llog_data *cld, *cld_prev;
540 int rand = prandom_u32_max(MGC_TIMEOUT_RAND_CENTISEC);
541 int to;
542
543
544 rq_state &= ~(RQ_NOW | RQ_LATER);
545 spin_unlock(&config_list_lock);
546
547 if (first) {
548 first = false;
549 complete(&rq_start);
550 }
551
552
553
554
555
556 to = msecs_to_jiffies(MGC_TIMEOUT_MIN_SECONDS * MSEC_PER_SEC);
557
558 to += msecs_to_jiffies(rand * MSEC_PER_SEC / 100);
559 lwi = LWI_TIMEOUT(to, NULL, NULL);
560 l_wait_event(rq_waitq, rq_state & (RQ_STOP | RQ_PRECLEANUP),
561 &lwi);
562
563
564
565
566
567
568
569
570
571 cld_prev = NULL;
572
573 spin_lock(&config_list_lock);
574 rq_state &= ~RQ_PRECLEANUP;
575 list_for_each_entry(cld, &config_llog_list, cld_list_chain) {
576 if (!cld->cld_lostlock || cld->cld_stopping)
577 continue;
578
579
580
581
582
583 config_log_get(cld);
584 cld->cld_lostlock = 0;
585 spin_unlock(&config_list_lock);
586
587 if (cld_prev)
588 config_log_put(cld_prev);
589 cld_prev = cld;
590
591 if (likely(!(rq_state & RQ_STOP))) {
592 do_requeue(cld);
593 spin_lock(&config_list_lock);
594 } else {
595 spin_lock(&config_list_lock);
596 break;
597 }
598 }
599 spin_unlock(&config_list_lock);
600 if (cld_prev)
601 config_log_put(cld_prev);
602
603
604 lwi = (struct l_wait_info) { 0 };
605 l_wait_event(rq_waitq, rq_state & (RQ_NOW | RQ_STOP),
606 &lwi);
607 spin_lock(&config_list_lock);
608 }
609
610
611 rq_state &= ~RQ_RUNNING;
612 spin_unlock(&config_list_lock);
613
614 complete(&rq_exit);
615
616 CDEBUG(D_MGC, "Ending requeue thread\n");
617 return 0;
618}
619
620
621
622
623static void mgc_requeue_add(struct config_llog_data *cld)
624{
625 bool wakeup = false;
626
627 CDEBUG(D_INFO, "log %s: requeue (r=%d sp=%d st=%x)\n",
628 cld->cld_logname, atomic_read(&cld->cld_refcount),
629 cld->cld_stopping, rq_state);
630 LASSERT(atomic_read(&cld->cld_refcount) > 0);
631
632 mutex_lock(&cld->cld_lock);
633 spin_lock(&config_list_lock);
634 if (!(rq_state & RQ_STOP) && !cld->cld_stopping && !cld->cld_lostlock) {
635 cld->cld_lostlock = 1;
636 rq_state |= RQ_NOW;
637 wakeup = true;
638 }
639 spin_unlock(&config_list_lock);
640 mutex_unlock(&cld->cld_lock);
641 if (wakeup)
642 wake_up(&rq_waitq);
643}
644
645static int mgc_llog_init(const struct lu_env *env, struct obd_device *obd)
646{
647 struct llog_ctxt *ctxt;
648 int rc;
649
650
651
652
653 rc = llog_setup(env, obd, &obd->obd_olg, LLOG_CONFIG_REPL_CTXT, obd,
654 &llog_client_ops);
655 if (rc)
656 return rc;
657
658 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
659 LASSERT(ctxt);
660
661 llog_initiator_connect(ctxt);
662 llog_ctxt_put(ctxt);
663
664 return 0;
665}
666
667static int mgc_llog_fini(const struct lu_env *env, struct obd_device *obd)
668{
669 struct llog_ctxt *ctxt;
670
671 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
672 if (ctxt)
673 llog_cleanup(env, ctxt);
674
675 return 0;
676}
677
678static atomic_t mgc_count = ATOMIC_INIT(0);
679static int mgc_precleanup(struct obd_device *obd)
680{
681 int rc = 0;
682 int temp;
683
684 if (atomic_dec_and_test(&mgc_count)) {
685 LASSERT(rq_state & RQ_RUNNING);
686
687 temp = RQ_STOP;
688 } else {
689
690 temp = RQ_NOW | RQ_PRECLEANUP;
691 }
692
693 spin_lock(&config_list_lock);
694 rq_state |= temp;
695 spin_unlock(&config_list_lock);
696 wake_up(&rq_waitq);
697
698 if (temp & RQ_STOP)
699 wait_for_completion(&rq_exit);
700 obd_cleanup_client_import(obd);
701
702 rc = mgc_llog_fini(NULL, obd);
703 if (rc)
704 CERROR("failed to cleanup llogging subsystems\n");
705
706 return rc;
707}
708
709static int mgc_cleanup(struct obd_device *obd)
710{
711
712
713
714 if (obd->obd_type->typ_refcnt <= 1)
715
716 class_del_profiles();
717
718 lprocfs_obd_cleanup(obd);
719 ptlrpcd_decref();
720
721 return client_obd_cleanup(obd);
722}
723
724static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
725{
726 struct lprocfs_static_vars lvars = { NULL };
727 struct task_struct *task;
728 int rc;
729
730 rc = ptlrpcd_addref();
731 if (rc < 0)
732 goto err_noref;
733
734 rc = client_obd_setup(obd, lcfg);
735 if (rc)
736 goto err_decref;
737
738 rc = mgc_llog_init(NULL, obd);
739 if (rc) {
740 CERROR("failed to setup llogging subsystems\n");
741 goto err_cleanup;
742 }
743
744 lprocfs_mgc_init_vars(&lvars);
745 lprocfs_obd_setup(obd, lvars.obd_vars, lvars.sysfs_vars);
746 sptlrpc_lprocfs_cliobd_attach(obd);
747
748 if (atomic_inc_return(&mgc_count) == 1) {
749 rq_state = 0;
750 init_waitqueue_head(&rq_waitq);
751
752
753 task = kthread_run(mgc_requeue_thread, NULL, "ll_cfg_requeue");
754 if (IS_ERR(task)) {
755 rc = PTR_ERR(task);
756 CERROR("%s: cannot start requeue thread: rc = %d; no more log updates\n",
757 obd->obd_name, rc);
758 goto err_cleanup;
759 }
760
761 rc = 0;
762 wait_for_completion(&rq_start);
763 }
764
765 return rc;
766
767err_cleanup:
768 client_obd_cleanup(obd);
769err_decref:
770 ptlrpcd_decref();
771err_noref:
772 return rc;
773}
774
775
776static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
777 void *data, int flag)
778{
779 struct lustre_handle lockh;
780 struct config_llog_data *cld = data;
781 int rc = 0;
782
783 switch (flag) {
784 case LDLM_CB_BLOCKING:
785
786 LDLM_DEBUG(lock, "MGC blocking CB");
787 ldlm_lock2handle(lock, &lockh);
788 rc = ldlm_cli_cancel(&lockh, LCF_ASYNC);
789 break;
790 case LDLM_CB_CANCELING:
791
792 LDLM_DEBUG(lock, "MGC cancel CB");
793
794 CDEBUG(D_MGC, "Lock res " DLDLMRES " (%.8s)\n",
795 PLDLMRES(lock->l_resource),
796 (char *)&lock->l_resource->lr_name.name[0]);
797
798 if (!cld) {
799 CDEBUG(D_INFO, "missing data, won't requeue\n");
800 break;
801 }
802
803
804 LASSERT(atomic_read(&cld->cld_refcount) > 0);
805
806 lock->l_ast_data = NULL;
807
808 if (cld->cld_stopping) {
809 CDEBUG(D_MGC, "log %s: stopping, won't requeue\n",
810 cld->cld_logname);
811 config_log_put(cld);
812 break;
813 }
814
815
816
817 if (!lock->l_conn_export ||
818 !lock->l_conn_export->exp_obd->u.cli.cl_conn_count) {
819 CDEBUG(D_MGC, "log %.8s: disconnecting, won't requeue\n",
820 cld->cld_logname);
821 config_log_put(cld);
822 break;
823 }
824
825
826 mgc_requeue_add(cld);
827 config_log_put(cld);
828 break;
829 default:
830 LBUG();
831 }
832
833 return rc;
834}
835
836
837
838
839
840#define MGC_ENQUEUE_LIMIT (INITIAL_CONNECT_TIMEOUT + (AT_OFF ? 0 : at_min) \
841 + PING_INTERVAL)
842#define MGC_TARGET_REG_LIMIT 10
843#define MGC_SEND_PARAM_LIMIT 10
844
845
846static int mgc_set_mgs_param(struct obd_export *exp,
847 struct mgs_send_param *msp)
848{
849 struct ptlrpc_request *req;
850 struct mgs_send_param *req_msp, *rep_msp;
851 int rc;
852
853 req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp),
854 &RQF_MGS_SET_INFO, LUSTRE_MGS_VERSION,
855 MGS_SET_INFO);
856 if (!req)
857 return -ENOMEM;
858
859 req_msp = req_capsule_client_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
860 if (!req_msp) {
861 ptlrpc_req_finished(req);
862 return -ENOMEM;
863 }
864
865 memcpy(req_msp, msp, sizeof(*req_msp));
866 ptlrpc_request_set_replen(req);
867
868
869 req->rq_delay_limit = MGC_SEND_PARAM_LIMIT;
870 rc = ptlrpc_queue_wait(req);
871 if (!rc) {
872 rep_msp = req_capsule_server_get(&req->rq_pill, &RMF_MGS_SEND_PARAM);
873 memcpy(msp, rep_msp, sizeof(*rep_msp));
874 }
875
876 ptlrpc_req_finished(req);
877
878 return rc;
879}
880
881
882static int mgc_enqueue(struct obd_export *exp, __u32 type,
883 union ldlm_policy_data *policy, __u32 mode,
884 __u64 *flags, void *bl_cb, void *cp_cb, void *gl_cb,
885 void *data, __u32 lvb_len, void *lvb_swabber,
886 struct lustre_handle *lockh)
887{
888 struct config_llog_data *cld = data;
889 struct ldlm_enqueue_info einfo = {
890 .ei_type = type,
891 .ei_mode = mode,
892 .ei_cb_bl = mgc_blocking_ast,
893 .ei_cb_cp = ldlm_completion_ast,
894 };
895 struct ptlrpc_request *req;
896 int short_limit = cld_is_sptlrpc(cld);
897 int rc;
898
899 CDEBUG(D_MGC, "Enqueue for %s (res %#llx)\n", cld->cld_logname,
900 cld->cld_resid.name[0]);
901
902
903
904
905 req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp),
906 &RQF_LDLM_ENQUEUE, LUSTRE_DLM_VERSION,
907 LDLM_ENQUEUE);
908 if (!req)
909 return -ENOMEM;
910
911 req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER, 0);
912 ptlrpc_request_set_replen(req);
913
914
915 req->rq_delay_limit = short_limit ? 5 : MGC_ENQUEUE_LIMIT;
916 rc = ldlm_cli_enqueue(exp, &req, &einfo, &cld->cld_resid, NULL, flags,
917 NULL, 0, LVB_T_NONE, lockh, 0);
918
919
920
921 ptlrpc_req_finished(req);
922 return rc;
923}
924
925static void mgc_notify_active(struct obd_device *unused)
926{
927
928 spin_lock(&config_list_lock);
929 rq_state |= RQ_NOW;
930 spin_unlock(&config_list_lock);
931 wake_up(&rq_waitq);
932
933
934}
935
936
937static int mgc_target_register(struct obd_export *exp,
938 struct mgs_target_info *mti)
939{
940 struct ptlrpc_request *req;
941 struct mgs_target_info *req_mti, *rep_mti;
942 int rc;
943
944 req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp),
945 &RQF_MGS_TARGET_REG, LUSTRE_MGS_VERSION,
946 MGS_TARGET_REG);
947 if (!req)
948 return -ENOMEM;
949
950 req_mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO);
951 if (!req_mti) {
952 ptlrpc_req_finished(req);
953 return -ENOMEM;
954 }
955
956 memcpy(req_mti, mti, sizeof(*req_mti));
957 ptlrpc_request_set_replen(req);
958 CDEBUG(D_MGC, "register %s\n", mti->mti_svname);
959
960 req->rq_delay_limit = MGC_TARGET_REG_LIMIT;
961
962 rc = ptlrpc_queue_wait(req);
963 if (!rc) {
964 rep_mti = req_capsule_server_get(&req->rq_pill,
965 &RMF_MGS_TARGET_INFO);
966 memcpy(mti, rep_mti, sizeof(*rep_mti));
967 CDEBUG(D_MGC, "register %s got index = %d\n",
968 mti->mti_svname, mti->mti_stripe_index);
969 }
970 ptlrpc_req_finished(req);
971
972 return rc;
973}
974
975static int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp,
976 u32 keylen, void *key, u32 vallen,
977 void *val, struct ptlrpc_request_set *set)
978{
979 int rc = -EINVAL;
980
981
982 if (KEY_IS(KEY_INIT_RECOV_BACKUP)) {
983 struct obd_import *imp = class_exp2cliimp(exp);
984 int value;
985
986 if (vallen != sizeof(int))
987 return -EINVAL;
988 value = *(int *)val;
989 CDEBUG(D_MGC, "InitRecov %s %d/d%d:i%d:r%d:or%d:%s\n",
990 imp->imp_obd->obd_name, value,
991 imp->imp_deactive, imp->imp_invalid,
992 imp->imp_replayable, imp->imp_obd->obd_replayable,
993 ptlrpc_import_state_name(imp->imp_state));
994
995 if ((imp->imp_state != LUSTRE_IMP_FULL &&
996 imp->imp_state != LUSTRE_IMP_NEW) || value > 1)
997 ptlrpc_reconnect_import(imp);
998 return 0;
999 }
1000 if (KEY_IS(KEY_SET_INFO)) {
1001 struct mgs_send_param *msp;
1002
1003 msp = val;
1004 rc = mgc_set_mgs_param(exp, msp);
1005 return rc;
1006 }
1007 if (KEY_IS(KEY_MGSSEC)) {
1008 struct client_obd *cli = &exp->exp_obd->u.cli;
1009 struct sptlrpc_flavor flvr;
1010
1011
1012
1013
1014
1015
1016
1017
1018 if (vallen == 0) {
1019 if (cli->cl_flvr_mgc.sf_rpc != SPTLRPC_FLVR_INVALID)
1020 return 0;
1021 val = "null";
1022 vallen = 4;
1023 }
1024
1025 rc = sptlrpc_parse_flavor(val, &flvr);
1026 if (rc) {
1027 CERROR("invalid sptlrpc flavor %s to MGS\n",
1028 (char *)val);
1029 return rc;
1030 }
1031
1032
1033
1034
1035 if (cli->cl_flvr_mgc.sf_rpc == SPTLRPC_FLVR_INVALID) {
1036 cli->cl_flvr_mgc = flvr;
1037 } else if (memcmp(&cli->cl_flvr_mgc, &flvr,
1038 sizeof(flvr)) != 0) {
1039 char str[20];
1040
1041 sptlrpc_flavor2name(&cli->cl_flvr_mgc,
1042 str, sizeof(str));
1043 LCONSOLE_ERROR("asking sptlrpc flavor %s to MGS but currently %s is in use\n",
1044 (char *)val, str);
1045 rc = -EPERM;
1046 }
1047 return rc;
1048 }
1049
1050 return rc;
1051}
1052
1053static int mgc_get_info(const struct lu_env *env, struct obd_export *exp,
1054 __u32 keylen, void *key, __u32 *vallen, void *val)
1055{
1056 int rc = -EINVAL;
1057
1058 if (KEY_IS(KEY_CONN_DATA)) {
1059 struct obd_import *imp = class_exp2cliimp(exp);
1060 struct obd_connect_data *data = val;
1061
1062 if (*vallen == sizeof(*data)) {
1063 *data = imp->imp_connect_data;
1064 rc = 0;
1065 }
1066 }
1067
1068 return rc;
1069}
1070
1071static int mgc_import_event(struct obd_device *obd,
1072 struct obd_import *imp,
1073 enum obd_import_event event)
1074{
1075 LASSERT(imp->imp_obd == obd);
1076 CDEBUG(D_MGC, "import event %#x\n", event);
1077
1078 switch (event) {
1079 case IMP_EVENT_DISCON:
1080
1081 if (OCD_HAS_FLAG(&imp->imp_connect_data, IMP_RECOV))
1082 ptlrpc_pinger_ir_down();
1083 break;
1084 case IMP_EVENT_INACTIVE:
1085 break;
1086 case IMP_EVENT_INVALIDATE: {
1087 struct ldlm_namespace *ns = obd->obd_namespace;
1088
1089 ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY);
1090 break;
1091 }
1092 case IMP_EVENT_ACTIVE:
1093 CDEBUG(D_INFO, "%s: Reactivating import\n", obd->obd_name);
1094
1095 obd->obd_no_recov = 0;
1096 mgc_notify_active(obd);
1097 if (OCD_HAS_FLAG(&imp->imp_connect_data, IMP_RECOV))
1098 ptlrpc_pinger_ir_up();
1099 break;
1100 case IMP_EVENT_OCD:
1101 break;
1102 case IMP_EVENT_DEACTIVATE:
1103 case IMP_EVENT_ACTIVATE:
1104 break;
1105 default:
1106 CERROR("Unknown import event %#x\n", event);
1107 LBUG();
1108 }
1109 return 0;
1110}
1111
1112enum {
1113 CONFIG_READ_NRPAGES_INIT = 1 << (20 - PAGE_SHIFT),
1114 CONFIG_READ_NRPAGES = 4
1115};
1116
1117static int mgc_apply_recover_logs(struct obd_device *mgc,
1118 struct config_llog_data *cld,
1119 __u64 max_version,
1120 void *data, int datalen, bool mne_swab)
1121{
1122 struct config_llog_instance *cfg = &cld->cld_cfg;
1123 struct mgs_nidtbl_entry *entry;
1124 struct lustre_cfg *lcfg;
1125 struct lustre_cfg_bufs bufs;
1126 u64 prev_version = 0;
1127 char *inst;
1128 char *buf;
1129 int bufsz;
1130 int pos;
1131 int rc = 0;
1132 int off = 0;
1133
1134 LASSERT(cfg->cfg_instance);
1135 LASSERT(cfg->cfg_sb == cfg->cfg_instance);
1136
1137 inst = kzalloc(PAGE_SIZE, GFP_KERNEL);
1138 if (!inst)
1139 return -ENOMEM;
1140
1141 pos = snprintf(inst, PAGE_SIZE, "%p", cfg->cfg_instance);
1142 if (pos >= PAGE_SIZE) {
1143 kfree(inst);
1144 return -E2BIG;
1145 }
1146
1147 ++pos;
1148 buf = inst + pos;
1149 bufsz = PAGE_SIZE - pos;
1150
1151 while (datalen > 0) {
1152 int entry_len = sizeof(*entry);
1153 int is_ost, i;
1154 struct obd_device *obd;
1155 char *obdname;
1156 char *cname;
1157 char *params;
1158 char *uuid;
1159 size_t len;
1160
1161 rc = -EINVAL;
1162 if (datalen < sizeof(*entry))
1163 break;
1164
1165 entry = (typeof(entry))(data + off);
1166
1167
1168 if (entry->mne_nid_type != 0)
1169 break;
1170 if (entry->mne_nid_count == 0)
1171 break;
1172 if (entry->mne_nid_size != sizeof(lnet_nid_t))
1173 break;
1174
1175 entry_len += entry->mne_nid_count * entry->mne_nid_size;
1176 if (datalen < entry_len)
1177 break;
1178
1179
1180 if (mne_swab)
1181 lustre_swab_mgs_nidtbl_entry(entry);
1182 if (entry->mne_length > PAGE_SIZE) {
1183 CERROR("MNE too large (%u)\n", entry->mne_length);
1184 break;
1185 }
1186
1187 if (entry->mne_length < entry_len)
1188 break;
1189
1190 off += entry->mne_length;
1191 datalen -= entry->mne_length;
1192 if (datalen < 0)
1193 break;
1194
1195 if (entry->mne_version > max_version) {
1196 CERROR("entry index(%lld) is over max_index(%lld)\n",
1197 entry->mne_version, max_version);
1198 break;
1199 }
1200
1201 if (prev_version >= entry->mne_version) {
1202 CERROR("index unsorted, prev %lld, now %lld\n",
1203 prev_version, entry->mne_version);
1204 break;
1205 }
1206 prev_version = entry->mne_version;
1207
1208
1209
1210
1211
1212
1213 is_ost = entry->mne_type == LDD_F_SV_TYPE_OST;
1214 memset(buf, 0, bufsz);
1215 obdname = buf;
1216 pos = 0;
1217
1218
1219 strcpy(obdname, cld->cld_logname);
1220 cname = strrchr(obdname, '-');
1221 if (!cname) {
1222 CERROR("mgc %s: invalid logname %s\n",
1223 mgc->obd_name, obdname);
1224 break;
1225 }
1226
1227 pos = cname - obdname;
1228 obdname[pos] = 0;
1229 pos += sprintf(obdname + pos, "-%s%04x",
1230 is_ost ? "OST" : "MDT", entry->mne_index);
1231
1232 cname = is_ost ? "osc" : "mdc";
1233 pos += sprintf(obdname + pos, "-%s-%s", cname, inst);
1234 lustre_cfg_bufs_reset(&bufs, obdname);
1235
1236
1237 obd = class_name2obd(obdname);
1238 if (!obd) {
1239 CDEBUG(D_INFO, "mgc %s: cannot find obdname %s\n",
1240 mgc->obd_name, obdname);
1241 rc = 0;
1242
1243 continue;
1244 }
1245
1246
1247 ++pos;
1248 params = buf + pos;
1249 pos += sprintf(params, "%s.import=%s", cname, "connection=");
1250 uuid = buf + pos;
1251
1252 down_read(&obd->u.cli.cl_sem);
1253 if (!obd->u.cli.cl_import) {
1254
1255 up_read(&obd->u.cli.cl_sem);
1256 rc = 0;
1257 continue;
1258 }
1259
1260
1261
1262 rc = -ENOENT;
1263 for (i = 0; i < entry->mne_nid_count; i++) {
1264 rc = client_import_find_conn(obd->u.cli.cl_import,
1265 entry->u.nids[0],
1266 (struct obd_uuid *)uuid);
1267 if (!rc)
1268 break;
1269 }
1270
1271 up_read(&obd->u.cli.cl_sem);
1272 if (rc < 0) {
1273 CERROR("mgc: cannot find uuid by nid %s\n",
1274 libcfs_nid2str(entry->u.nids[0]));
1275 break;
1276 }
1277
1278 CDEBUG(D_INFO, "Find uuid %s by nid %s\n",
1279 uuid, libcfs_nid2str(entry->u.nids[0]));
1280
1281 pos += strlen(uuid);
1282 pos += sprintf(buf + pos, "::%u", entry->mne_instance);
1283 LASSERT(pos < bufsz);
1284
1285 lustre_cfg_bufs_set_string(&bufs, 1, params);
1286
1287 rc = -ENOMEM;
1288 len = lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen);
1289 lcfg = kzalloc(len, GFP_NOFS);
1290 if (!lcfg) {
1291 rc = -ENOMEM;
1292 break;
1293 }
1294 lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
1295
1296 CDEBUG(D_INFO, "ir apply logs %lld/%lld for %s -> %s\n",
1297 prev_version, max_version, obdname, params);
1298
1299 rc = class_process_config(lcfg);
1300 kfree(lcfg);
1301 if (rc)
1302 CDEBUG(D_INFO, "process config for %s error %d\n",
1303 obdname, rc);
1304
1305
1306 }
1307
1308 kfree(inst);
1309 return rc;
1310}
1311
1312
1313
1314
1315
1316static int mgc_process_recover_log(struct obd_device *obd,
1317 struct config_llog_data *cld)
1318{
1319 struct ptlrpc_request *req = NULL;
1320 struct config_llog_instance *cfg = &cld->cld_cfg;
1321 struct mgs_config_body *body;
1322 struct mgs_config_res *res;
1323 struct ptlrpc_bulk_desc *desc;
1324 struct page **pages;
1325 int nrpages;
1326 bool eof = true;
1327 bool mne_swab;
1328 int i;
1329 int ealen;
1330 int rc;
1331
1332
1333
1334
1335
1336
1337
1338 nrpages = CONFIG_READ_NRPAGES;
1339 if (cfg->cfg_last_idx == 0)
1340 nrpages = CONFIG_READ_NRPAGES_INIT;
1341
1342 pages = kcalloc(nrpages, sizeof(*pages), GFP_KERNEL);
1343 if (!pages) {
1344 rc = -ENOMEM;
1345 goto out;
1346 }
1347
1348 for (i = 0; i < nrpages; i++) {
1349 pages[i] = alloc_page(GFP_KERNEL);
1350 if (!pages[i]) {
1351 rc = -ENOMEM;
1352 goto out;
1353 }
1354 }
1355
1356again:
1357 LASSERT(cld_is_recover(cld));
1358 LASSERT(mutex_is_locked(&cld->cld_lock));
1359 req = ptlrpc_request_alloc(class_exp2cliimp(cld->cld_mgcexp),
1360 &RQF_MGS_CONFIG_READ);
1361 if (!req) {
1362 rc = -ENOMEM;
1363 goto out;
1364 }
1365
1366 rc = ptlrpc_request_pack(req, LUSTRE_MGS_VERSION, MGS_CONFIG_READ);
1367 if (rc)
1368 goto out;
1369
1370
1371 body = req_capsule_client_get(&req->rq_pill, &RMF_MGS_CONFIG_BODY);
1372 LASSERT(sizeof(body->mcb_name) > strlen(cld->cld_logname));
1373 if (strlcpy(body->mcb_name, cld->cld_logname, sizeof(body->mcb_name))
1374 >= sizeof(body->mcb_name)) {
1375 rc = -E2BIG;
1376 goto out;
1377 }
1378 body->mcb_offset = cfg->cfg_last_idx + 1;
1379 body->mcb_type = cld->cld_type;
1380 body->mcb_bits = PAGE_SHIFT;
1381 body->mcb_units = nrpages;
1382
1383
1384 desc = ptlrpc_prep_bulk_imp(req, nrpages, 1,
1385 PTLRPC_BULK_PUT_SINK | PTLRPC_BULK_BUF_KIOV,
1386 MGS_BULK_PORTAL,
1387 &ptlrpc_bulk_kiov_pin_ops);
1388 if (!desc) {
1389 rc = -ENOMEM;
1390 goto out;
1391 }
1392
1393 for (i = 0; i < nrpages; i++)
1394 desc->bd_frag_ops->add_kiov_frag(desc, pages[i], 0, PAGE_SIZE);
1395
1396 ptlrpc_request_set_replen(req);
1397 rc = ptlrpc_queue_wait(req);
1398 if (rc)
1399 goto out;
1400
1401 res = req_capsule_server_get(&req->rq_pill, &RMF_MGS_CONFIG_RES);
1402 if (res->mcr_size < res->mcr_offset) {
1403 rc = -EINVAL;
1404 goto out;
1405 }
1406
1407
1408
1409
1410 cfg->cfg_last_idx = res->mcr_offset;
1411 eof = res->mcr_offset == res->mcr_size;
1412
1413 CDEBUG(D_INFO, "Latest version %lld, more %d.\n",
1414 res->mcr_offset, eof == false);
1415
1416 ealen = sptlrpc_cli_unwrap_bulk_read(req, req->rq_bulk, 0);
1417 if (ealen < 0) {
1418 rc = ealen;
1419 goto out;
1420 }
1421
1422 if (ealen > nrpages << PAGE_SHIFT) {
1423 rc = -EINVAL;
1424 goto out;
1425 }
1426
1427 if (ealen == 0) {
1428 if (!eof)
1429 rc = -EINVAL;
1430 goto out;
1431 }
1432
1433 mne_swab = !!ptlrpc_rep_need_swab(req);
1434#if OBD_OCD_VERSION(3, 0, 53, 0) > LUSTRE_VERSION_CODE
1435
1436
1437
1438 if (unlikely(req->rq_import->imp_need_mne_swab))
1439 mne_swab = !mne_swab;
1440#endif
1441
1442 for (i = 0; i < nrpages && ealen > 0; i++) {
1443 int rc2;
1444 void *ptr;
1445
1446 ptr = kmap(pages[i]);
1447 rc2 = mgc_apply_recover_logs(obd, cld, res->mcr_offset, ptr,
1448 min_t(int, ealen, PAGE_SIZE),
1449 mne_swab);
1450 kunmap(pages[i]);
1451 if (rc2 < 0) {
1452 CWARN("Process recover log %s error %d\n",
1453 cld->cld_logname, rc2);
1454 break;
1455 }
1456
1457 ealen -= PAGE_SIZE;
1458 }
1459
1460out:
1461 if (req)
1462 ptlrpc_req_finished(req);
1463
1464 if (rc == 0 && !eof)
1465 goto again;
1466
1467 if (pages) {
1468 for (i = 0; i < nrpages; i++) {
1469 if (!pages[i])
1470 break;
1471 __free_page(pages[i]);
1472 }
1473 kfree(pages);
1474 }
1475 return rc;
1476}
1477
1478
1479static int mgc_process_cfg_log(struct obd_device *mgc,
1480 struct config_llog_data *cld, int local_only)
1481{
1482 struct llog_ctxt *ctxt;
1483 struct lustre_sb_info *lsi = NULL;
1484 int rc = 0;
1485 bool sptlrpc_started = false;
1486 struct lu_env *env;
1487
1488 LASSERT(cld);
1489 LASSERT(mutex_is_locked(&cld->cld_lock));
1490
1491
1492
1493
1494
1495 if (cld_is_sptlrpc(cld) && local_only)
1496 return 0;
1497
1498 if (cld->cld_cfg.cfg_sb)
1499 lsi = s2lsi(cld->cld_cfg.cfg_sb);
1500
1501 env = kzalloc(sizeof(*env), GFP_KERNEL);
1502 if (!env)
1503 return -ENOMEM;
1504
1505 rc = lu_env_init(env, LCT_MG_THREAD);
1506 if (rc)
1507 goto out_free;
1508
1509 ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT);
1510 LASSERT(ctxt);
1511
1512 if (local_only) {
1513 rc = -EIO;
1514 goto out_pop;
1515 }
1516
1517 if (cld_is_sptlrpc(cld)) {
1518 sptlrpc_conf_log_update_begin(cld->cld_logname);
1519 sptlrpc_started = true;
1520 }
1521
1522
1523
1524
1525
1526 rc = class_config_parse_llog(env, ctxt, cld->cld_logname,
1527 &cld->cld_cfg);
1528
1529out_pop:
1530 __llog_ctxt_put(env, ctxt);
1531
1532
1533
1534
1535
1536
1537
1538 if (sptlrpc_started) {
1539 LASSERT(cld_is_sptlrpc(cld));
1540 sptlrpc_conf_log_update_end(cld->cld_logname);
1541 class_notify_sptlrpc_conf(cld->cld_logname,
1542 strlen(cld->cld_logname) -
1543 strlen("-sptlrpc"));
1544 }
1545
1546 lu_env_fini(env);
1547out_free:
1548 kfree(env);
1549 return rc;
1550}
1551
1552static bool mgc_import_in_recovery(struct obd_import *imp)
1553{
1554 bool in_recovery = true;
1555
1556 spin_lock(&imp->imp_lock);
1557 if (imp->imp_state == LUSTRE_IMP_FULL ||
1558 imp->imp_state == LUSTRE_IMP_CLOSED)
1559 in_recovery = false;
1560 spin_unlock(&imp->imp_lock);
1561
1562 return in_recovery;
1563}
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld)
1594{
1595 struct lustre_handle lockh = { 0 };
1596 __u64 flags = LDLM_FL_NO_LRU;
1597 bool retry = false;
1598 int rc = 0, rcl;
1599
1600 LASSERT(cld);
1601
1602
1603
1604
1605
1606
1607restart:
1608 mutex_lock(&cld->cld_lock);
1609 if (cld->cld_stopping) {
1610 mutex_unlock(&cld->cld_lock);
1611 return 0;
1612 }
1613
1614 OBD_FAIL_TIMEOUT(OBD_FAIL_MGC_PAUSE_PROCESS_LOG, 20);
1615
1616 CDEBUG(D_MGC, "Process log %s:%p from %d\n", cld->cld_logname,
1617 cld->cld_cfg.cfg_instance, cld->cld_cfg.cfg_last_idx + 1);
1618
1619
1620 rcl = mgc_enqueue(mgc->u.cli.cl_mgc_mgsexp, LDLM_PLAIN, NULL,
1621 LCK_CR, &flags, NULL, NULL, NULL,
1622 cld, 0, NULL, &lockh);
1623 if (rcl == 0) {
1624
1625 config_log_get(cld);
1626 rc = ldlm_lock_set_data(&lockh, (void *)cld);
1627 LASSERT(rc == 0);
1628 } else {
1629 CDEBUG(D_MGC, "Can't get cfg lock: %d\n", rcl);
1630
1631 if (rcl == -ESHUTDOWN &&
1632 atomic_read(&mgc->u.cli.cl_mgc_refcount) > 0 && !retry) {
1633 int secs = cfs_time_seconds(obd_timeout);
1634 struct obd_import *imp;
1635 struct l_wait_info lwi;
1636
1637 mutex_unlock(&cld->cld_lock);
1638 imp = class_exp2cliimp(mgc->u.cli.cl_mgc_mgsexp);
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648 ptlrpc_pinger_force(imp);
1649
1650 lwi = LWI_TIMEOUT(secs, NULL, NULL);
1651 l_wait_event(imp->imp_recovery_waitq,
1652 !mgc_import_in_recovery(imp), &lwi);
1653
1654 if (imp->imp_state == LUSTRE_IMP_FULL) {
1655 retry = true;
1656 goto restart;
1657 } else {
1658 mutex_lock(&cld->cld_lock);
1659 spin_lock(&config_list_lock);
1660 cld->cld_lostlock = 1;
1661 spin_unlock(&config_list_lock);
1662 }
1663 } else {
1664
1665
1666
1667 spin_lock(&config_list_lock);
1668 cld->cld_lostlock = 1;
1669 spin_unlock(&config_list_lock);
1670 }
1671 }
1672
1673 if (cld_is_recover(cld)) {
1674 rc = 0;
1675 if (!rcl) {
1676 rc = mgc_process_recover_log(mgc, cld);
1677 if (rc) {
1678 CERROR("%s: recover log %s failed: rc = %d not fatal.\n",
1679 mgc->obd_name, cld->cld_logname, rc);
1680 rc = 0;
1681 spin_lock(&config_list_lock);
1682 cld->cld_lostlock = 1;
1683 spin_unlock(&config_list_lock);
1684 }
1685 }
1686 } else {
1687 rc = mgc_process_cfg_log(mgc, cld, rcl != 0);
1688 }
1689
1690 CDEBUG(D_MGC, "%s: configuration from log '%s' %sed (%d).\n",
1691 mgc->obd_name, cld->cld_logname, rc ? "fail" : "succeed", rc);
1692
1693 mutex_unlock(&cld->cld_lock);
1694
1695
1696 if (!rcl)
1697 ldlm_lock_decref(&lockh, LCK_CR);
1698
1699 return rc;
1700}
1701
1702
1703
1704
1705
1706static int mgc_process_config(struct obd_device *obd, u32 len, void *buf)
1707{
1708 struct lustre_cfg *lcfg = buf;
1709 struct config_llog_instance *cfg = NULL;
1710 char *logname;
1711 int rc = 0;
1712
1713 switch (lcfg->lcfg_command) {
1714 case LCFG_LOV_ADD_OBD: {
1715
1716 struct mgs_target_info *mti;
1717
1718 if (LUSTRE_CFG_BUFLEN(lcfg, 1) !=
1719 sizeof(struct mgs_target_info)) {
1720 rc = -EINVAL;
1721 goto out;
1722 }
1723
1724 mti = (struct mgs_target_info *)lustre_cfg_buf(lcfg, 1);
1725 CDEBUG(D_MGC, "add_target %s %#x\n",
1726 mti->mti_svname, mti->mti_flags);
1727 rc = mgc_target_register(obd->u.cli.cl_mgc_mgsexp, mti);
1728 break;
1729 }
1730 case LCFG_LOV_DEL_OBD:
1731
1732 CERROR("lov_del_obd unimplemented\n");
1733 rc = -ENOSYS;
1734 break;
1735 case LCFG_SPTLRPC_CONF: {
1736 rc = sptlrpc_process_config(lcfg);
1737 break;
1738 }
1739 case LCFG_LOG_START: {
1740 struct config_llog_data *cld;
1741 struct super_block *sb;
1742
1743 logname = lustre_cfg_string(lcfg, 1);
1744 cfg = (struct config_llog_instance *)lustre_cfg_buf(lcfg, 2);
1745 sb = *(struct super_block **)lustre_cfg_buf(lcfg, 3);
1746
1747 CDEBUG(D_MGC, "parse_log %s from %d\n", logname,
1748 cfg->cfg_last_idx);
1749
1750
1751 cld = config_log_add(obd, logname, cfg, sb);
1752 if (IS_ERR(cld)) {
1753 rc = PTR_ERR(cld);
1754 break;
1755 }
1756
1757
1758
1759
1760
1761 cld->cld_cfg.cfg_flags |= CFG_F_COMPAT146;
1762
1763 rc = mgc_process_log(obd, cld);
1764 if (rc == 0 && cld->cld_recover) {
1765 if (OCD_HAS_FLAG(&obd->u.cli.cl_import->
1766 imp_connect_data, IMP_RECOV)) {
1767 rc = mgc_process_log(obd, cld->cld_recover);
1768 } else {
1769 struct config_llog_data *cir;
1770
1771 mutex_lock(&cld->cld_lock);
1772 cir = cld->cld_recover;
1773 cld->cld_recover = NULL;
1774 mutex_unlock(&cld->cld_lock);
1775 config_log_put(cir);
1776 }
1777
1778 if (rc)
1779 CERROR("Cannot process recover llog %d\n", rc);
1780 }
1781
1782 if (rc == 0 && cld->cld_params) {
1783 rc = mgc_process_log(obd, cld->cld_params);
1784 if (rc == -ENOENT) {
1785 CDEBUG(D_MGC,
1786 "There is no params config file yet\n");
1787 rc = 0;
1788 }
1789
1790 if (rc)
1791 CERROR(
1792 "%s: can't process params llog: rc = %d\n",
1793 obd->obd_name, rc);
1794 }
1795
1796 break;
1797 }
1798 case LCFG_LOG_END: {
1799 logname = lustre_cfg_string(lcfg, 1);
1800
1801 if (lcfg->lcfg_bufcount >= 2)
1802 cfg = (struct config_llog_instance *)lustre_cfg_buf(
1803 lcfg, 2);
1804 rc = config_log_end(logname, cfg);
1805 break;
1806 }
1807 default: {
1808 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
1809 rc = -EINVAL;
1810 goto out;
1811 }
1812 }
1813out:
1814 return rc;
1815}
1816
1817static struct obd_ops mgc_obd_ops = {
1818 .owner = THIS_MODULE,
1819 .setup = mgc_setup,
1820 .precleanup = mgc_precleanup,
1821 .cleanup = mgc_cleanup,
1822 .add_conn = client_import_add_conn,
1823 .del_conn = client_import_del_conn,
1824 .connect = client_connect_import,
1825 .disconnect = client_disconnect_export,
1826 .set_info_async = mgc_set_info_async,
1827 .get_info = mgc_get_info,
1828 .import_event = mgc_import_event,
1829 .process_config = mgc_process_config,
1830};
1831
1832static int __init mgc_init(void)
1833{
1834 return class_register_type(&mgc_obd_ops, NULL,
1835 LUSTRE_MGC_NAME, NULL);
1836}
1837
1838static void mgc_exit(void)
1839{
1840 class_unregister_type(LUSTRE_MGC_NAME);
1841}
1842
1843MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
1844MODULE_DESCRIPTION("Lustre Management Client");
1845MODULE_VERSION(LUSTRE_VERSION_STRING);
1846MODULE_LICENSE("GPL");
1847
1848module_init(mgc_init);
1849module_exit(mgc_exit);
1850