| .. | .. |
|---|
| 39 | 39 | /* |
|---|
| 40 | 40 | * Decode a monmap blob (e.g., during mount). |
|---|
| 41 | 41 | */ |
|---|
| 42 | | -struct ceph_monmap *ceph_monmap_decode(void *p, void *end) |
|---|
| 42 | +static struct ceph_monmap *ceph_monmap_decode(void *p, void *end) |
|---|
| 43 | 43 | { |
|---|
| 44 | 44 | struct ceph_monmap *m = NULL; |
|---|
| 45 | 45 | int i, err = -EINVAL; |
|---|
| .. | .. |
|---|
| 50 | 50 | ceph_decode_32_safe(&p, end, len, bad); |
|---|
| 51 | 51 | ceph_decode_need(&p, end, len, bad); |
|---|
| 52 | 52 | |
|---|
| 53 | | - dout("monmap_decode %p %p len %d\n", p, end, (int)(end-p)); |
|---|
| 53 | + dout("monmap_decode %p %p len %d (%d)\n", p, end, len, (int)(end-p)); |
|---|
| 54 | 54 | p += sizeof(u16); /* skip version */ |
|---|
| 55 | 55 | |
|---|
| 56 | 56 | ceph_decode_need(&p, end, sizeof(fsid) + 2*sizeof(u32), bad); |
|---|
| .. | .. |
|---|
| 58 | 58 | epoch = ceph_decode_32(&p); |
|---|
| 59 | 59 | |
|---|
| 60 | 60 | num_mon = ceph_decode_32(&p); |
|---|
| 61 | | - ceph_decode_need(&p, end, num_mon*sizeof(m->mon_inst[0]), bad); |
|---|
| 62 | 61 | |
|---|
| 63 | 62 | if (num_mon > CEPH_MAX_MON) |
|---|
| 64 | 63 | goto bad; |
|---|
| .. | .. |
|---|
| 68 | 67 | m->fsid = fsid; |
|---|
| 69 | 68 | m->epoch = epoch; |
|---|
| 70 | 69 | m->num_mon = num_mon; |
|---|
| 71 | | - ceph_decode_copy(&p, m->mon_inst, num_mon*sizeof(m->mon_inst[0])); |
|---|
| 72 | | - for (i = 0; i < num_mon; i++) |
|---|
| 73 | | - ceph_decode_addr(&m->mon_inst[i].addr); |
|---|
| 70 | + for (i = 0; i < num_mon; ++i) { |
|---|
| 71 | + struct ceph_entity_inst *inst = &m->mon_inst[i]; |
|---|
| 74 | 72 | |
|---|
| 73 | + /* copy name portion */ |
|---|
| 74 | + ceph_decode_copy_safe(&p, end, &inst->name, |
|---|
| 75 | + sizeof(inst->name), bad); |
|---|
| 76 | + err = ceph_decode_entity_addr(&p, end, &inst->addr); |
|---|
| 77 | + if (err) |
|---|
| 78 | + goto bad; |
|---|
| 79 | + } |
|---|
| 75 | 80 | dout("monmap_decode epoch %d, num_mon %d\n", m->epoch, |
|---|
| 76 | 81 | m->num_mon); |
|---|
| 77 | 82 | for (i = 0; i < m->num_mon; i++) |
|---|
| 78 | 83 | dout("monmap_decode mon%d is %s\n", i, |
|---|
| 79 | | - ceph_pr_addr(&m->mon_inst[i].addr.in_addr)); |
|---|
| 84 | + ceph_pr_addr(&m->mon_inst[i].addr)); |
|---|
| 80 | 85 | return m; |
|---|
| 81 | | - |
|---|
| 82 | 86 | bad: |
|---|
| 83 | 87 | dout("monmap_decode failed with %d\n", err); |
|---|
| 84 | 88 | kfree(m); |
|---|
| .. | .. |
|---|
| 92 | 96 | { |
|---|
| 93 | 97 | int i; |
|---|
| 94 | 98 | |
|---|
| 95 | | - for (i = 0; i < m->num_mon; i++) |
|---|
| 96 | | - if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0) |
|---|
| 99 | + for (i = 0; i < m->num_mon; i++) { |
|---|
| 100 | + if (ceph_addr_equal_no_type(addr, &m->mon_inst[i].addr)) |
|---|
| 97 | 101 | return 1; |
|---|
| 102 | + } |
|---|
| 103 | + |
|---|
| 98 | 104 | return 0; |
|---|
| 99 | 105 | } |
|---|
| 100 | 106 | |
|---|
| .. | .. |
|---|
| 203 | 209 | { |
|---|
| 204 | 210 | if (!monc->hunting) |
|---|
| 205 | 211 | pr_info("mon%d %s session lost, hunting for new mon\n", |
|---|
| 206 | | - monc->cur_mon, ceph_pr_addr(&monc->con.peer_addr.in_addr)); |
|---|
| 212 | + monc->cur_mon, ceph_pr_addr(&monc->con.peer_addr)); |
|---|
| 207 | 213 | |
|---|
| 208 | 214 | __close_session(monc); |
|---|
| 209 | 215 | __open_session(monc); |
|---|
| 216 | +} |
|---|
| 217 | + |
|---|
| 218 | +void ceph_monc_reopen_session(struct ceph_mon_client *monc) |
|---|
| 219 | +{ |
|---|
| 220 | + mutex_lock(&monc->mutex); |
|---|
| 221 | + reopen_session(monc); |
|---|
| 222 | + mutex_unlock(&monc->mutex); |
|---|
| 210 | 223 | } |
|---|
| 211 | 224 | |
|---|
| 212 | 225 | static void un_backoff(struct ceph_mon_client *monc) |
|---|
| .. | .. |
|---|
| 456 | 469 | struct ceph_msg *msg) |
|---|
| 457 | 470 | { |
|---|
| 458 | 471 | struct ceph_client *client = monc->client; |
|---|
| 459 | | - struct ceph_monmap *monmap = NULL, *old = monc->monmap; |
|---|
| 472 | + struct ceph_monmap *monmap; |
|---|
| 460 | 473 | void *p, *end; |
|---|
| 461 | 474 | |
|---|
| 462 | 475 | mutex_lock(&monc->mutex); |
|---|
| .. | .. |
|---|
| 469 | 482 | if (IS_ERR(monmap)) { |
|---|
| 470 | 483 | pr_err("problem decoding monmap, %d\n", |
|---|
| 471 | 484 | (int)PTR_ERR(monmap)); |
|---|
| 485 | + ceph_msg_dump(msg); |
|---|
| 472 | 486 | goto out; |
|---|
| 473 | 487 | } |
|---|
| 474 | 488 | |
|---|
| 475 | | - if (ceph_check_fsid(monc->client, &monmap->fsid) < 0) { |
|---|
| 489 | + if (ceph_check_fsid(client, &monmap->fsid) < 0) { |
|---|
| 476 | 490 | kfree(monmap); |
|---|
| 477 | 491 | goto out; |
|---|
| 478 | 492 | } |
|---|
| 479 | 493 | |
|---|
| 480 | | - client->monc.monmap = monmap; |
|---|
| 481 | | - kfree(old); |
|---|
| 494 | + kfree(monc->monmap); |
|---|
| 495 | + monc->monmap = monmap; |
|---|
| 482 | 496 | |
|---|
| 483 | 497 | __ceph_monc_got_map(monc, CEPH_SUB_MONMAP, monc->monmap->epoch); |
|---|
| 484 | 498 | client->have_fsid = true; |
|---|
| .. | .. |
|---|
| 884 | 898 | ceph_msg_dump(msg); |
|---|
| 885 | 899 | } |
|---|
| 886 | 900 | |
|---|
| 887 | | -int ceph_monc_blacklist_add(struct ceph_mon_client *monc, |
|---|
| 888 | | - struct ceph_entity_addr *client_addr) |
|---|
| 901 | +static __printf(2, 0) |
|---|
| 902 | +int do_mon_command_vargs(struct ceph_mon_client *monc, const char *fmt, |
|---|
| 903 | + va_list ap) |
|---|
| 889 | 904 | { |
|---|
| 890 | 905 | struct ceph_mon_generic_request *req; |
|---|
| 891 | 906 | struct ceph_mon_command *h; |
|---|
| .. | .. |
|---|
| 913 | 928 | h->monhdr.session_mon_tid = 0; |
|---|
| 914 | 929 | h->fsid = monc->monmap->fsid; |
|---|
| 915 | 930 | h->num_strs = cpu_to_le32(1); |
|---|
| 916 | | - len = sprintf(h->str, "{ \"prefix\": \"osd blacklist\", \ |
|---|
| 917 | | - \"blacklistop\": \"add\", \ |
|---|
| 918 | | - \"addr\": \"%pISpc/%u\" }", |
|---|
| 919 | | - &client_addr->in_addr, le32_to_cpu(client_addr->nonce)); |
|---|
| 931 | + len = vsprintf(h->str, fmt, ap); |
|---|
| 920 | 932 | h->str_len = cpu_to_le32(len); |
|---|
| 921 | 933 | send_generic_request(monc, req); |
|---|
| 922 | 934 | mutex_unlock(&monc->mutex); |
|---|
| 923 | 935 | |
|---|
| 924 | 936 | ret = wait_generic_request(req); |
|---|
| 925 | | - if (!ret) |
|---|
| 926 | | - /* |
|---|
| 927 | | - * Make sure we have the osdmap that includes the blacklist |
|---|
| 928 | | - * entry. This is needed to ensure that the OSDs pick up the |
|---|
| 929 | | - * new blacklist before processing any future requests from |
|---|
| 930 | | - * this client. |
|---|
| 931 | | - */ |
|---|
| 932 | | - ret = ceph_wait_for_latest_osdmap(monc->client, 0); |
|---|
| 933 | | - |
|---|
| 934 | 937 | out: |
|---|
| 935 | 938 | put_generic_request(req); |
|---|
| 936 | 939 | return ret; |
|---|
| 937 | 940 | } |
|---|
| 938 | | -EXPORT_SYMBOL(ceph_monc_blacklist_add); |
|---|
| 941 | + |
|---|
| 942 | +static __printf(2, 3) |
|---|
| 943 | +int do_mon_command(struct ceph_mon_client *monc, const char *fmt, ...) |
|---|
| 944 | +{ |
|---|
| 945 | + va_list ap; |
|---|
| 946 | + int ret; |
|---|
| 947 | + |
|---|
| 948 | + va_start(ap, fmt); |
|---|
| 949 | + ret = do_mon_command_vargs(monc, fmt, ap); |
|---|
| 950 | + va_end(ap); |
|---|
| 951 | + return ret; |
|---|
| 952 | +} |
|---|
| 953 | + |
|---|
| 954 | +int ceph_monc_blocklist_add(struct ceph_mon_client *monc, |
|---|
| 955 | + struct ceph_entity_addr *client_addr) |
|---|
| 956 | +{ |
|---|
| 957 | + int ret; |
|---|
| 958 | + |
|---|
| 959 | + ret = do_mon_command(monc, |
|---|
| 960 | + "{ \"prefix\": \"osd blocklist\", \ |
|---|
| 961 | + \"blocklistop\": \"add\", \ |
|---|
| 962 | + \"addr\": \"%pISpc/%u\" }", |
|---|
| 963 | + &client_addr->in_addr, |
|---|
| 964 | + le32_to_cpu(client_addr->nonce)); |
|---|
| 965 | + if (ret == -EINVAL) { |
|---|
| 966 | + /* |
|---|
| 967 | + * The monitor returns EINVAL on an unrecognized command. |
|---|
| 968 | + * Try the legacy command -- it is exactly the same except |
|---|
| 969 | + * for the name. |
|---|
| 970 | + */ |
|---|
| 971 | + ret = do_mon_command(monc, |
|---|
| 972 | + "{ \"prefix\": \"osd blacklist\", \ |
|---|
| 973 | + \"blacklistop\": \"add\", \ |
|---|
| 974 | + \"addr\": \"%pISpc/%u\" }", |
|---|
| 975 | + &client_addr->in_addr, |
|---|
| 976 | + le32_to_cpu(client_addr->nonce)); |
|---|
| 977 | + } |
|---|
| 978 | + if (ret) |
|---|
| 979 | + return ret; |
|---|
| 980 | + |
|---|
| 981 | + /* |
|---|
| 982 | + * Make sure we have the osdmap that includes the blocklist |
|---|
| 983 | + * entry. This is needed to ensure that the OSDs pick up the |
|---|
| 984 | + * new blocklist before processing any future requests from |
|---|
| 985 | + * this client. |
|---|
| 986 | + */ |
|---|
| 987 | + return ceph_wait_for_latest_osdmap(monc->client, 0); |
|---|
| 988 | +} |
|---|
| 989 | +EXPORT_SYMBOL(ceph_monc_blocklist_add); |
|---|
| 939 | 990 | |
|---|
| 940 | 991 | /* |
|---|
| 941 | 992 | * Resend pending generic requests. |
|---|
| .. | .. |
|---|
| 1178 | 1229 | __resend_generic_request(monc); |
|---|
| 1179 | 1230 | |
|---|
| 1180 | 1231 | pr_info("mon%d %s session established\n", monc->cur_mon, |
|---|
| 1181 | | - ceph_pr_addr(&monc->con.peer_addr.in_addr)); |
|---|
| 1232 | + ceph_pr_addr(&monc->con.peer_addr)); |
|---|
| 1182 | 1233 | } |
|---|
| 1183 | 1234 | |
|---|
| 1184 | 1235 | out: |
|---|
| .. | .. |
|---|
| 1220 | 1271 | { |
|---|
| 1221 | 1272 | struct ceph_mon_client *monc = con->private; |
|---|
| 1222 | 1273 | int type = le16_to_cpu(msg->hdr.type); |
|---|
| 1223 | | - |
|---|
| 1224 | | - if (!monc) |
|---|
| 1225 | | - return; |
|---|
| 1226 | 1274 | |
|---|
| 1227 | 1275 | switch (type) { |
|---|
| 1228 | 1276 | case CEPH_MSG_AUTH_REPLY: |
|---|
| .. | .. |
|---|
| 1298 | 1346 | * request had a non-zero tid. Work around this weirdness |
|---|
| 1299 | 1347 | * by allocating a new message. |
|---|
| 1300 | 1348 | */ |
|---|
| 1301 | | - /* fall through */ |
|---|
| 1349 | + fallthrough; |
|---|
| 1302 | 1350 | case CEPH_MSG_MON_MAP: |
|---|
| 1303 | 1351 | case CEPH_MSG_MDS_MAP: |
|---|
| 1304 | 1352 | case CEPH_MSG_OSD_MAP: |
|---|