aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mon_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/mon_client.c')
-rw-r--r--fs/ceph/mon_client.c210
1 files changed, 170 insertions, 40 deletions
diff --git a/fs/ceph/mon_client.c b/fs/ceph/mon_client.c
index 95b76e761e18..017d5aef8834 100644
--- a/fs/ceph/mon_client.c
+++ b/fs/ceph/mon_client.c
@@ -6,6 +6,7 @@
6 6
7#include "mon_client.h" 7#include "mon_client.h"
8#include "super.h" 8#include "super.h"
9#include "auth.h"
9#include "decode.h" 10#include "decode.h"
10 11
11/* 12/*
@@ -38,6 +39,10 @@ struct ceph_monmap *ceph_monmap_decode(void *p, void *end)
38 struct ceph_fsid fsid; 39 struct ceph_fsid fsid;
39 u32 epoch, num_mon; 40 u32 epoch, num_mon;
40 u16 version; 41 u16 version;
42 u32 len;
43
44 ceph_decode_32_safe(&p, end, len, bad);
45 ceph_decode_need(&p, end, len, bad);
41 46
42 dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p)); 47 dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p));
43 48
@@ -95,8 +100,10 @@ static void __close_session(struct ceph_mon_client *monc)
95{ 100{
96 if (monc->con) { 101 if (monc->con) {
97 dout("__close_session closing mon%d\n", monc->cur_mon); 102 dout("__close_session closing mon%d\n", monc->cur_mon);
103 ceph_con_revoke(monc->con, monc->m_auth);
98 ceph_con_close(monc->con); 104 ceph_con_close(monc->con);
99 monc->cur_mon = -1; 105 monc->cur_mon = -1;
106 ceph_auth_reset(monc->auth);
100 } 107 }
101} 108}
102 109
@@ -106,6 +113,7 @@ static void __close_session(struct ceph_mon_client *monc)
106static int __open_session(struct ceph_mon_client *monc) 113static int __open_session(struct ceph_mon_client *monc)
107{ 114{
108 char r; 115 char r;
116 int ret;
109 117
110 if (monc->cur_mon < 0) { 118 if (monc->cur_mon < 0) {
111 get_random_bytes(&r, 1); 119 get_random_bytes(&r, 1);
@@ -121,6 +129,15 @@ static int __open_session(struct ceph_mon_client *monc)
121 monc->con->peer_name.num = cpu_to_le64(monc->cur_mon); 129 monc->con->peer_name.num = cpu_to_le64(monc->cur_mon);
122 ceph_con_open(monc->con, 130 ceph_con_open(monc->con,
123 &monc->monmap->mon_inst[monc->cur_mon].addr); 131 &monc->monmap->mon_inst[monc->cur_mon].addr);
132
133 /* initiatiate authentication handshake */
134 ret = ceph_auth_build_hello(monc->auth,
135 monc->m_auth->front.iov_base,
136 monc->m_auth->front_max);
137 monc->m_auth->front.iov_len = ret;
138 monc->m_auth->hdr.front_len = cpu_to_le32(ret);
139 ceph_msg_get(monc->m_auth); /* keep our ref */
140 ceph_con_send(monc->con, monc->m_auth);
124 } else { 141 } else {
125 dout("open_session mon%d already open\n", monc->cur_mon); 142 dout("open_session mon%d already open\n", monc->cur_mon);
126 } 143 }
@@ -139,7 +156,7 @@ static void __schedule_delayed(struct ceph_mon_client *monc)
139{ 156{
140 unsigned delay; 157 unsigned delay;
141 158
142 if (monc->cur_mon < 0 || monc->want_mount || __sub_expired(monc)) 159 if (monc->cur_mon < 0 || __sub_expired(monc))
143 delay = 10 * HZ; 160 delay = 10 * HZ;
144 else 161 else
145 delay = 20 * HZ; 162 delay = 20 * HZ;
@@ -161,7 +178,7 @@ static void __send_subscribe(struct ceph_mon_client *monc)
161 struct ceph_mon_subscribe_item *i; 178 struct ceph_mon_subscribe_item *i;
162 void *p, *end; 179 void *p, *end;
163 180
164 msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 64, 0, 0, NULL); 181 msg = ceph_msg_new(CEPH_MSG_MON_SUBSCRIBE, 96, 0, 0, NULL);
165 if (!msg) 182 if (!msg)
166 return; 183 return;
167 184
@@ -173,7 +190,7 @@ static void __send_subscribe(struct ceph_mon_client *monc)
173 if (monc->want_next_osdmap) { 190 if (monc->want_next_osdmap) {
174 dout("__send_subscribe to 'osdmap' %u\n", 191 dout("__send_subscribe to 'osdmap' %u\n",
175 (unsigned)monc->have_osdmap); 192 (unsigned)monc->have_osdmap);
176 ceph_encode_32(&p, 2); 193 ceph_encode_32(&p, 3);
177 ceph_encode_string(&p, end, "osdmap", 6); 194 ceph_encode_string(&p, end, "osdmap", 6);
178 i = p; 195 i = p;
179 i->have = cpu_to_le64(monc->have_osdmap); 196 i->have = cpu_to_le64(monc->have_osdmap);
@@ -181,13 +198,18 @@ static void __send_subscribe(struct ceph_mon_client *monc)
181 p += sizeof(*i); 198 p += sizeof(*i);
182 monc->want_next_osdmap = 2; /* requested */ 199 monc->want_next_osdmap = 2; /* requested */
183 } else { 200 } else {
184 ceph_encode_32(&p, 1); 201 ceph_encode_32(&p, 2);
185 } 202 }
186 ceph_encode_string(&p, end, "mdsmap", 6); 203 ceph_encode_string(&p, end, "mdsmap", 6);
187 i = p; 204 i = p;
188 i->have = cpu_to_le64(monc->have_mdsmap); 205 i->have = cpu_to_le64(monc->have_mdsmap);
189 i->onetime = 0; 206 i->onetime = 0;
190 p += sizeof(*i); 207 p += sizeof(*i);
208 ceph_encode_string(&p, end, "monmap", 6);
209 i = p;
210 i->have = 0;
211 i->onetime = 0;
212 p += sizeof(*i);
191 213
192 msg->front.iov_len = p - msg->front.iov_base; 214 msg->front.iov_len = p - msg->front.iov_base;
193 msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); 215 msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
@@ -256,7 +278,7 @@ void ceph_monc_request_next_osdmap(struct ceph_mon_client *monc)
256 mutex_unlock(&monc->mutex); 278 mutex_unlock(&monc->mutex);
257} 279}
258 280
259 281#if 0
260/* 282/*
261 * mount 283 * mount
262 */ 284 */
@@ -264,12 +286,8 @@ static void __request_mount(struct ceph_mon_client *monc)
264{ 286{
265 struct ceph_msg *msg; 287 struct ceph_msg *msg;
266 struct ceph_client_mount *h; 288 struct ceph_client_mount *h;
267 int err;
268 289
269 dout("__request_mount\n"); 290 dout("__request_mount\n");
270 err = __open_session(monc);
271 if (err)
272 return;
273 msg = ceph_msg_new(CEPH_MSG_CLIENT_MOUNT, sizeof(*h), 0, 0, NULL); 291 msg = ceph_msg_new(CEPH_MSG_CLIENT_MOUNT, sizeof(*h), 0, 0, NULL);
274 if (IS_ERR(msg)) 292 if (IS_ERR(msg))
275 return; 293 return;
@@ -279,8 +297,12 @@ static void __request_mount(struct ceph_mon_client *monc)
279 h->monhdr.session_mon_tid = 0; 297 h->monhdr.session_mon_tid = 0;
280 ceph_con_send(monc->con, msg); 298 ceph_con_send(monc->con, msg);
281} 299}
300#endif
282 301
283int ceph_monc_request_mount(struct ceph_mon_client *monc) 302/*
303 *
304 */
305int ceph_monc_open_session(struct ceph_mon_client *monc)
284{ 306{
285 if (!monc->con) { 307 if (!monc->con) {
286 monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL); 308 monc->con = kmalloc(sizeof(*monc->con), GFP_KERNEL);
@@ -292,12 +314,14 @@ int ceph_monc_request_mount(struct ceph_mon_client *monc)
292 } 314 }
293 315
294 mutex_lock(&monc->mutex); 316 mutex_lock(&monc->mutex);
295 __request_mount(monc); 317 __open_session(monc);
296 __schedule_delayed(monc); 318 __schedule_delayed(monc);
297 mutex_unlock(&monc->mutex); 319 mutex_unlock(&monc->mutex);
298 return 0; 320 return 0;
299} 321}
300 322
323#if 0
324
301/* 325/*
302 * The monitor responds with mount ack indicate mount success. The 326 * The monitor responds with mount ack indicate mount success. The
303 * included client ticket allows the client to talk to MDSs and OSDs. 327 * included client ticket allows the client to talk to MDSs and OSDs.
@@ -372,9 +396,65 @@ out:
372 mutex_unlock(&monc->mutex); 396 mutex_unlock(&monc->mutex);
373 wake_up(&client->mount_wq); 397 wake_up(&client->mount_wq);
374} 398}
399#endif
400
401/*
402 * The monitor responds with mount ack indicate mount success. The
403 * included client ticket allows the client to talk to MDSs and OSDs.
404 */
405static void ceph_monc_handle_map(struct ceph_mon_client *monc, struct ceph_msg *msg)
406{
407 struct ceph_client *client = monc->client;
408 struct ceph_monmap *monmap = NULL, *old = monc->monmap;
409 void *p, *end;
410
411 mutex_lock(&monc->mutex);
412
413 dout("handle_monmap\n");
414 p = msg->front.iov_base;
415 end = p + msg->front.iov_len;
416
417 monmap = ceph_monmap_decode(p, end);
418 if (IS_ERR(monmap)) {
419 pr_err("problem decoding monmap, %d\n",
420 (int)PTR_ERR(monmap));
421 return;
422 }
423 if (monc->have_fsid &&
424 ceph_fsid_compare(&monmap->fsid, &monc->monmap->fsid)) {
425 print_hex_dump(KERN_ERR, "monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1,
426 (void *)&monmap->fsid, 16, 0);
427 print_hex_dump(KERN_ERR, "monc->monmap->fsid: ", DUMP_PREFIX_NONE, 16, 1,
428 (void *)&monc->monmap->fsid, 16, 0);
429
430 pr_err("fsid mismatch, got a previous map with different fsid");
431 kfree(monmap);
432 return;
433 }
434
435 client->monc.monmap = monmap;
436 client->monc.have_fsid = true;
437 kfree(old);
438
439 mutex_unlock(&monc->mutex);
440 wake_up(&client->mount_wq);
441}
442
375 443
444/*
445 * init client info after authentication
446 */
447static void __init_authenticated_client(struct ceph_mon_client *monc)
448{
449 struct ceph_client *client = monc->client;
376 450
451 client->signed_ticket = NULL;
452 client->signed_ticket_len = 0;
453 client->msgr->inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
454 client->msgr->inst.name.num = monc->auth->global_id;
377 455
456 ceph_debugfs_client_init(client);
457}
378 458
379/* 459/*
380 * statfs 460 * statfs
@@ -414,12 +494,8 @@ static int send_statfs(struct ceph_mon_client *monc,
414{ 494{
415 struct ceph_msg *msg; 495 struct ceph_msg *msg;
416 struct ceph_mon_statfs *h; 496 struct ceph_mon_statfs *h;
417 int err;
418 497
419 dout("send_statfs tid %llu\n", req->tid); 498 dout("send_statfs tid %llu\n", req->tid);
420 err = __open_session(monc);
421 if (err)
422 return err;
423 msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL); 499 msg = ceph_msg_new(CEPH_MSG_STATFS, sizeof(*h), 0, 0, NULL);
424 if (IS_ERR(msg)) 500 if (IS_ERR(msg))
425 return PTR_ERR(msg); 501 return PTR_ERR(msg);
@@ -514,17 +590,14 @@ static void delayed_work(struct work_struct *work)
514 590
515 dout("monc delayed_work\n"); 591 dout("monc delayed_work\n");
516 mutex_lock(&monc->mutex); 592 mutex_lock(&monc->mutex);
517 if (monc->want_mount) { 593 if (monc->hunting) {
518 __request_mount(monc); 594 __close_session(monc);
595 __open_session(monc); /* continue hunting */
519 } else { 596 } else {
520 if (monc->hunting) { 597 ceph_con_keepalive(monc->con);
521 __close_session(monc); 598 if (monc->auth->ops->is_authenticated(monc->auth))
522 __open_session(monc); /* continue hunting */ 599 __send_subscribe(monc);
523 } else {
524 ceph_con_keepalive(monc->con);
525 }
526 } 600 }
527 __send_subscribe(monc);
528 __schedule_delayed(monc); 601 __schedule_delayed(monc);
529 mutex_unlock(&monc->mutex); 602 mutex_unlock(&monc->mutex);
530} 603}
@@ -555,6 +628,7 @@ static int build_initial_monmap(struct ceph_mon_client *monc)
555 monc->monmap->mon_inst[i].name.num = cpu_to_le64(i); 628 monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
556 } 629 }
557 monc->monmap->num_mon = num_mon; 630 monc->monmap->num_mon = num_mon;
631 monc->have_fsid = false;
558 632
559 /* release addr memory */ 633 /* release addr memory */
560 kfree(args->mon_addr); 634 kfree(args->mon_addr);
@@ -579,21 +653,37 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
579 653
580 monc->con = NULL; 654 monc->con = NULL;
581 655
656 /* authentication */
657 monc->auth = ceph_auth_init(cl->mount_args->name,
658 cl->mount_args->secret);
659 if (IS_ERR(monc->auth))
660 return PTR_ERR(monc->auth);
661 monc->auth->want_keys =
662 CEPH_ENTITY_TYPE_AUTH | CEPH_ENTITY_TYPE_MON |
663 CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MDS;
664
582 /* msg pools */ 665 /* msg pools */
583 err = ceph_msgpool_init(&monc->msgpool_mount_ack, 4096, 1, false);
584 if (err < 0)
585 goto out;
586 err = ceph_msgpool_init(&monc->msgpool_subscribe_ack, 666 err = ceph_msgpool_init(&monc->msgpool_subscribe_ack,
587 sizeof(struct ceph_mon_subscribe_ack), 1, false); 667 sizeof(struct ceph_mon_subscribe_ack), 1, false);
588 if (err < 0) 668 if (err < 0)
589 goto out; 669 goto out_monmap;
590 err = ceph_msgpool_init(&monc->msgpool_statfs_reply, 670 err = ceph_msgpool_init(&monc->msgpool_statfs_reply,
591 sizeof(struct ceph_mon_statfs_reply), 0, false); 671 sizeof(struct ceph_mon_statfs_reply), 0, false);
592 if (err < 0) 672 if (err < 0)
593 goto out; 673 goto out_pool1;
674 err = ceph_msgpool_init(&monc->msgpool_auth_reply, 4096, 1, false);
675 if (err < 0)
676 goto out_pool2;
677
678 monc->m_auth = ceph_msg_new(CEPH_MSG_AUTH, 4096, 0, 0, NULL);
679 if (IS_ERR(monc->m_auth)) {
680 err = PTR_ERR(monc->m_auth);
681 monc->m_auth = NULL;
682 goto out_pool3;
683 }
594 684
595 monc->cur_mon = -1; 685 monc->cur_mon = -1;
596 monc->hunting = false; /* not really */ 686 monc->hunting = true;
597 monc->sub_renew_after = jiffies; 687 monc->sub_renew_after = jiffies;
598 monc->sub_sent = 0; 688 monc->sub_sent = 0;
599 689
@@ -605,7 +695,16 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
605 monc->have_mdsmap = 0; 695 monc->have_mdsmap = 0;
606 monc->have_osdmap = 0; 696 monc->have_osdmap = 0;
607 monc->want_next_osdmap = 1; 697 monc->want_next_osdmap = 1;
608 monc->want_mount = true; 698 return 0;
699
700out_pool3:
701 ceph_msgpool_destroy(&monc->msgpool_auth_reply);
702out_pool2:
703 ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
704out_pool1:
705 ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
706out_monmap:
707 kfree(monc->monmap);
609out: 708out:
610 return err; 709 return err;
611} 710}
@@ -624,14 +723,44 @@ void ceph_monc_stop(struct ceph_mon_client *monc)
624 } 723 }
625 mutex_unlock(&monc->mutex); 724 mutex_unlock(&monc->mutex);
626 725
627 ceph_msgpool_destroy(&monc->msgpool_mount_ack); 726 ceph_auth_destroy(monc->auth);
727
728 ceph_msg_put(monc->m_auth);
628 ceph_msgpool_destroy(&monc->msgpool_subscribe_ack); 729 ceph_msgpool_destroy(&monc->msgpool_subscribe_ack);
629 ceph_msgpool_destroy(&monc->msgpool_statfs_reply); 730 ceph_msgpool_destroy(&monc->msgpool_statfs_reply);
731 ceph_msgpool_destroy(&monc->msgpool_auth_reply);
630 732
631 kfree(monc->monmap); 733 kfree(monc->monmap);
632} 734}
633 735
634 736
737static void handle_auth_reply(struct ceph_mon_client *monc,
738 struct ceph_msg *msg)
739{
740 int ret;
741
742 mutex_lock(&monc->mutex);
743 ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base,
744 msg->front.iov_len,
745 monc->m_auth->front.iov_base,
746 monc->m_auth->front_max);
747 if (ret < 0) {
748 monc->client->mount_err = ret;
749 wake_up(&monc->client->mount_wq);
750 } else if (ret > 0) {
751 monc->m_auth->front.iov_len = ret;
752 monc->m_auth->hdr.front_len = cpu_to_le32(ret);
753 ceph_msg_get(monc->m_auth); /* keep our ref */
754 ceph_con_send(monc->con, monc->m_auth);
755 } else if (monc->auth->ops->is_authenticated(monc->auth)) {
756 dout("authenticated, starting session\n");
757 __init_authenticated_client(monc);
758 __send_subscribe(monc);
759 __resend_statfs(monc);
760 }
761 mutex_unlock(&monc->mutex);
762}
763
635/* 764/*
636 * handle incoming message 765 * handle incoming message
637 */ 766 */
@@ -644,8 +773,8 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
644 return; 773 return;
645 774
646 switch (type) { 775 switch (type) {
647 case CEPH_MSG_CLIENT_MOUNT_ACK: 776 case CEPH_MSG_AUTH_REPLY:
648 handle_mount_ack(monc, msg); 777 handle_auth_reply(monc, msg);
649 break; 778 break;
650 779
651 case CEPH_MSG_MON_SUBSCRIBE_ACK: 780 case CEPH_MSG_MON_SUBSCRIBE_ACK:
@@ -656,6 +785,10 @@ static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
656 handle_statfs_reply(monc, msg); 785 handle_statfs_reply(monc, msg);
657 break; 786 break;
658 787
788 case CEPH_MSG_MON_MAP:
789 ceph_monc_handle_map(monc, msg);
790 break;
791
659 case CEPH_MSG_MDS_MAP: 792 case CEPH_MSG_MDS_MAP:
660 ceph_mdsc_handle_map(&monc->client->mdsc, msg); 793 ceph_mdsc_handle_map(&monc->client->mdsc, msg);
661 break; 794 break;
@@ -682,12 +815,12 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con,
682 int front = le32_to_cpu(hdr->front_len); 815 int front = le32_to_cpu(hdr->front_len);
683 816
684 switch (type) { 817 switch (type) {
685 case CEPH_MSG_CLIENT_MOUNT_ACK:
686 return ceph_msgpool_get(&monc->msgpool_mount_ack, front);
687 case CEPH_MSG_MON_SUBSCRIBE_ACK: 818 case CEPH_MSG_MON_SUBSCRIBE_ACK:
688 return ceph_msgpool_get(&monc->msgpool_subscribe_ack, front); 819 return ceph_msgpool_get(&monc->msgpool_subscribe_ack, front);
689 case CEPH_MSG_STATFS_REPLY: 820 case CEPH_MSG_STATFS_REPLY:
690 return ceph_msgpool_get(&monc->msgpool_statfs_reply, front); 821 return ceph_msgpool_get(&monc->msgpool_statfs_reply, front);
822 case CEPH_MSG_AUTH_REPLY:
823 return ceph_msgpool_get(&monc->msgpool_auth_reply, front);
691 } 824 }
692 return ceph_alloc_msg(con, hdr); 825 return ceph_alloc_msg(con, hdr);
693} 826}
@@ -717,10 +850,7 @@ static void mon_fault(struct ceph_connection *con)
717 if (!monc->hunting) { 850 if (!monc->hunting) {
718 /* start hunting */ 851 /* start hunting */
719 monc->hunting = true; 852 monc->hunting = true;
720 if (__open_session(monc) == 0) { 853 __open_session(monc);
721 __send_subscribe(monc);
722 __resend_statfs(monc);
723 }
724 } else { 854 } else {
725 /* already hunting, let's wait a bit */ 855 /* already hunting, let's wait a bit */
726 __schedule_delayed(monc); 856 __schedule_delayed(monc);