aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/mon_client.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2009-11-18 19:19:57 -0500
committerSage Weil <sage@newdream.net>2009-11-18 19:19:57 -0500
commit4e7a5dcd1bbab6560fbc8ada29a840e7a20ed7bc (patch)
treea77e9b4563022340361ca673ef2e1beebb538e2f /fs/ceph/mon_client.c
parent5f44f142601bf94c448e2d463f0f18fd159da164 (diff)
ceph: negotiate authentication protocol; implement AUTH_NONE protocol
When we open a monitor session, we send an initial AUTH message listing the auth protocols we support, our entity name, and (possibly) a previously assigned global_id. The monitor chooses a protocol and responds with an initial message. Initially implement AUTH_NONE, a dummy protocol that provides no security, but works within the new framework. It generates 'authorizers' that are used when connecting to (mds, osd) services that simply state our entity name and global_id. This is a wire protocol change. Signed-off-by: Sage Weil <sage@newdream.net>
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);