1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * RDMA Network Block Driver 4 * 5 * Copyright (c) 2014 - 2018 ProfitBricks GmbH. All rights reserved. 6 * Copyright (c) 2018 - 2019 1&1 IONOS Cloud GmbH. All rights reserved. 7 * Copyright (c) 2019 - 2020 1&1 IONOS SE. All rights reserved. 8 */ 9 10 #undef pr_fmt 11 #define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt 12 13 #include <linux/types.h> 14 #include <linux/ctype.h> 15 #include <linux/parser.h> 16 #include <linux/module.h> 17 #include <linux/in6.h> 18 #include <linux/fs.h> 19 #include <linux/uaccess.h> 20 #include <linux/device.h> 21 #include <rdma/ib.h> 22 #include <rdma/rdma_cm.h> 23 24 #include "rnbd-clt.h" 25 26 static struct device *rnbd_dev; 27 static struct class *rnbd_dev_class; 28 static struct kobject *rnbd_devs_kobj; 29 30 enum { 31 RNBD_OPT_ERR = 0, 32 RNBD_OPT_DEST_PORT = 1 << 0, 33 RNBD_OPT_PATH = 1 << 1, 34 RNBD_OPT_DEV_PATH = 1 << 2, 35 RNBD_OPT_ACCESS_MODE = 1 << 3, 36 RNBD_OPT_SESSNAME = 1 << 6, 37 RNBD_OPT_NR_POLL_QUEUES = 1 << 7, 38 }; 39 40 static const unsigned int rnbd_opt_mandatory[] = { 41 RNBD_OPT_DEV_PATH, 42 RNBD_OPT_SESSNAME, 43 }; 44 45 static const match_table_t rnbd_opt_tokens = { 46 {RNBD_OPT_PATH, "path=%s" }, 47 {RNBD_OPT_DEV_PATH, "device_path=%s" }, 48 {RNBD_OPT_DEST_PORT, "dest_port=%d" }, 49 {RNBD_OPT_ACCESS_MODE, "access_mode=%s" }, 50 {RNBD_OPT_SESSNAME, "sessname=%s" }, 51 {RNBD_OPT_NR_POLL_QUEUES, "nr_poll_queues=%d" }, 52 {RNBD_OPT_ERR, NULL }, 53 }; 54 55 struct rnbd_map_options { 56 char *sessname; 57 struct rtrs_addr *paths; 58 size_t *path_cnt; 59 char *pathname; 60 u16 *dest_port; 61 enum rnbd_access_mode *access_mode; 62 u32 *nr_poll_queues; 63 }; 64 65 static int rnbd_clt_parse_map_options(const char *buf, size_t max_path_cnt, 66 struct rnbd_map_options *opt) 67 { 68 char *options, *sep_opt; 69 char *p; 70 substring_t args[MAX_OPT_ARGS]; 71 int opt_mask = 0; 72 int token; 73 int ret = -EINVAL; 74 int nr_poll_queues = 0; 75 int dest_port = 0; 76 int p_cnt = 0; 77 int i; 78 79 options = kstrdup(buf, GFP_KERNEL); 80 if (!options) 81 return -ENOMEM; 82 83 sep_opt = strstrip(options); 84 while ((p = strsep(&sep_opt, " ")) != NULL) { 85 if (!*p) 86 continue; 87 88 token = match_token(p, rnbd_opt_tokens, args); 89 opt_mask |= token; 90 91 switch (token) { 92 case RNBD_OPT_SESSNAME: 93 p = match_strdup(args); 94 if (!p) { 95 ret = -ENOMEM; 96 goto out; 97 } 98 if (strlen(p) > NAME_MAX) { 99 pr_err("map_device: sessname too long\n"); 100 ret = -EINVAL; 101 kfree(p); 102 goto out; 103 } 104 strscpy(opt->sessname, p, NAME_MAX); 105 kfree(p); 106 break; 107 108 case RNBD_OPT_PATH: 109 if (p_cnt >= max_path_cnt) { 110 pr_err("map_device: too many (> %zu) paths provided\n", 111 max_path_cnt); 112 ret = -ENOMEM; 113 goto out; 114 } 115 p = match_strdup(args); 116 if (!p) { 117 ret = -ENOMEM; 118 goto out; 119 } 120 121 ret = rtrs_addr_to_sockaddr(p, strlen(p), 122 *opt->dest_port, 123 &opt->paths[p_cnt]); 124 if (ret) { 125 pr_err("Can't parse path %s: %d\n", p, ret); 126 kfree(p); 127 goto out; 128 } 129 130 p_cnt++; 131 132 kfree(p); 133 break; 134 135 case RNBD_OPT_DEV_PATH: 136 p = match_strdup(args); 137 if (!p) { 138 ret = -ENOMEM; 139 goto out; 140 } 141 if (strlen(p) > NAME_MAX) { 142 pr_err("map_device: Device path too long\n"); 143 ret = -EINVAL; 144 kfree(p); 145 goto out; 146 } 147 strscpy(opt->pathname, p, NAME_MAX); 148 kfree(p); 149 break; 150 151 case RNBD_OPT_DEST_PORT: 152 if (match_int(args, &dest_port) || dest_port < 0 || 153 dest_port > 65535) { 154 pr_err("bad destination port number parameter '%d'\n", 155 dest_port); 156 ret = -EINVAL; 157 goto out; 158 } 159 *opt->dest_port = dest_port; 160 break; 161 162 case RNBD_OPT_ACCESS_MODE: 163 p = match_strdup(args); 164 if (!p) { 165 ret = -ENOMEM; 166 goto out; 167 } 168 169 if (!strcmp(p, "ro")) { 170 *opt->access_mode = RNBD_ACCESS_RO; 171 } else if (!strcmp(p, "rw")) { 172 *opt->access_mode = RNBD_ACCESS_RW; 173 } else if (!strcmp(p, "migration")) { 174 *opt->access_mode = RNBD_ACCESS_MIGRATION; 175 } else { 176 pr_err("map_device: Invalid access_mode: '%s'\n", 177 p); 178 ret = -EINVAL; 179 kfree(p); 180 goto out; 181 } 182 183 kfree(p); 184 break; 185 186 case RNBD_OPT_NR_POLL_QUEUES: 187 if (match_int(args, &nr_poll_queues) || nr_poll_queues < -1 || 188 nr_poll_queues > (int)nr_cpu_ids) { 189 pr_err("bad nr_poll_queues parameter '%d'\n", 190 nr_poll_queues); 191 ret = -EINVAL; 192 goto out; 193 } 194 if (nr_poll_queues == -1) 195 nr_poll_queues = nr_cpu_ids; 196 *opt->nr_poll_queues = nr_poll_queues; 197 break; 198 199 default: 200 pr_err("map_device: Unknown parameter or missing value '%s'\n", 201 p); 202 ret = -EINVAL; 203 goto out; 204 } 205 } 206 207 for (i = 0; i < ARRAY_SIZE(rnbd_opt_mandatory); i++) { 208 if ((opt_mask & rnbd_opt_mandatory[i])) { 209 ret = 0; 210 } else { 211 pr_err("map_device: Parameters missing\n"); 212 ret = -EINVAL; 213 break; 214 } 215 } 216 217 out: 218 *opt->path_cnt = p_cnt; 219 kfree(options); 220 return ret; 221 } 222 223 static ssize_t state_show(struct kobject *kobj, 224 struct kobj_attribute *attr, char *page) 225 { 226 struct rnbd_clt_dev *dev; 227 228 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 229 230 switch (dev->dev_state) { 231 case DEV_STATE_INIT: 232 return sysfs_emit(page, "init\n"); 233 case DEV_STATE_MAPPED: 234 /* TODO fix cli tool before changing to proper state */ 235 return sysfs_emit(page, "open\n"); 236 case DEV_STATE_MAPPED_DISCONNECTED: 237 /* TODO fix cli tool before changing to proper state */ 238 return sysfs_emit(page, "closed\n"); 239 case DEV_STATE_UNMAPPED: 240 return sysfs_emit(page, "unmapped\n"); 241 default: 242 return sysfs_emit(page, "unknown\n"); 243 } 244 } 245 246 static struct kobj_attribute rnbd_clt_state_attr = __ATTR_RO(state); 247 248 static ssize_t nr_poll_queues_show(struct kobject *kobj, 249 struct kobj_attribute *attr, char *page) 250 { 251 struct rnbd_clt_dev *dev; 252 253 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 254 255 return sysfs_emit(page, "%d\n", dev->nr_poll_queues); 256 } 257 258 static struct kobj_attribute rnbd_clt_nr_poll_queues = 259 __ATTR_RO(nr_poll_queues); 260 261 static ssize_t mapping_path_show(struct kobject *kobj, 262 struct kobj_attribute *attr, char *page) 263 { 264 struct rnbd_clt_dev *dev; 265 266 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 267 268 return sysfs_emit(page, "%s\n", dev->pathname); 269 } 270 271 static struct kobj_attribute rnbd_clt_mapping_path_attr = 272 __ATTR_RO(mapping_path); 273 274 static ssize_t access_mode_show(struct kobject *kobj, 275 struct kobj_attribute *attr, char *page) 276 { 277 struct rnbd_clt_dev *dev; 278 279 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 280 281 return sysfs_emit(page, "%s\n", rnbd_access_mode_str(dev->access_mode)); 282 } 283 284 static struct kobj_attribute rnbd_clt_access_mode = 285 __ATTR_RO(access_mode); 286 287 static ssize_t rnbd_clt_unmap_dev_show(struct kobject *kobj, 288 struct kobj_attribute *attr, char *page) 289 { 290 return sysfs_emit(page, "Usage: echo <normal|force> > %s\n", 291 attr->attr.name); 292 } 293 294 static ssize_t rnbd_clt_unmap_dev_store(struct kobject *kobj, 295 struct kobj_attribute *attr, 296 const char *buf, size_t count) 297 { 298 struct rnbd_clt_dev *dev; 299 char *opt, *options; 300 bool force; 301 int err; 302 303 opt = kstrdup(buf, GFP_KERNEL); 304 if (!opt) 305 return -ENOMEM; 306 307 options = strstrip(opt); 308 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 309 if (sysfs_streq(options, "normal")) { 310 force = false; 311 } else if (sysfs_streq(options, "force")) { 312 force = true; 313 } else { 314 rnbd_clt_err(dev, 315 "unmap_device: Invalid value: %s\n", 316 options); 317 err = -EINVAL; 318 goto out; 319 } 320 321 rnbd_clt_info(dev, "Unmapping device, option: %s.\n", 322 force ? "force" : "normal"); 323 324 /* 325 * We take explicit module reference only for one reason: do not 326 * race with lockless rnbd_destroy_sessions(). 327 */ 328 if (!try_module_get(THIS_MODULE)) { 329 err = -ENODEV; 330 goto out; 331 } 332 err = rnbd_clt_unmap_device(dev, force, &attr->attr); 333 if (err) { 334 if (err != -EALREADY) 335 rnbd_clt_err(dev, "unmap_device: %d\n", err); 336 goto module_put; 337 } 338 339 /* 340 * Here device can be vanished! 341 */ 342 343 err = count; 344 345 module_put: 346 module_put(THIS_MODULE); 347 out: 348 kfree(opt); 349 350 return err; 351 } 352 353 static struct kobj_attribute rnbd_clt_unmap_device_attr = 354 __ATTR(unmap_device, 0644, rnbd_clt_unmap_dev_show, 355 rnbd_clt_unmap_dev_store); 356 357 static ssize_t rnbd_clt_resize_dev_show(struct kobject *kobj, 358 struct kobj_attribute *attr, 359 char *page) 360 { 361 return sysfs_emit(page, "Usage: echo <new size in sectors> > %s\n", 362 attr->attr.name); 363 } 364 365 static ssize_t rnbd_clt_resize_dev_store(struct kobject *kobj, 366 struct kobj_attribute *attr, 367 const char *buf, size_t count) 368 { 369 int ret; 370 unsigned long sectors; 371 struct rnbd_clt_dev *dev; 372 373 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 374 375 ret = kstrtoul(buf, 0, §ors); 376 if (ret) 377 return ret; 378 379 ret = rnbd_clt_resize_disk(dev, (size_t)sectors); 380 if (ret) 381 return ret; 382 383 return count; 384 } 385 386 static struct kobj_attribute rnbd_clt_resize_dev_attr = 387 __ATTR(resize, 0644, rnbd_clt_resize_dev_show, 388 rnbd_clt_resize_dev_store); 389 390 static ssize_t rnbd_clt_remap_dev_show(struct kobject *kobj, 391 struct kobj_attribute *attr, char *page) 392 { 393 return sysfs_emit(page, "Usage: echo <1> > %s\n", attr->attr.name); 394 } 395 396 static ssize_t rnbd_clt_remap_dev_store(struct kobject *kobj, 397 struct kobj_attribute *attr, 398 const char *buf, size_t count) 399 { 400 struct rnbd_clt_dev *dev; 401 char *opt, *options; 402 int err; 403 404 opt = kstrdup(buf, GFP_KERNEL); 405 if (!opt) 406 return -ENOMEM; 407 408 options = strstrip(opt); 409 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 410 if (!sysfs_streq(options, "1")) { 411 rnbd_clt_err(dev, 412 "remap_device: Invalid value: %s\n", 413 options); 414 err = -EINVAL; 415 goto out; 416 } 417 err = rnbd_clt_remap_device(dev); 418 if (likely(!err)) 419 err = count; 420 421 out: 422 kfree(opt); 423 424 return err; 425 } 426 427 static struct kobj_attribute rnbd_clt_remap_device_attr = 428 __ATTR(remap_device, 0644, rnbd_clt_remap_dev_show, 429 rnbd_clt_remap_dev_store); 430 431 static ssize_t session_show(struct kobject *kobj, struct kobj_attribute *attr, 432 char *page) 433 { 434 struct rnbd_clt_dev *dev; 435 436 dev = container_of(kobj, struct rnbd_clt_dev, kobj); 437 438 return sysfs_emit(page, "%s\n", dev->sess->sessname); 439 } 440 441 static struct kobj_attribute rnbd_clt_session_attr = 442 __ATTR_RO(session); 443 444 static struct attribute *rnbd_dev_attrs[] = { 445 &rnbd_clt_unmap_device_attr.attr, 446 &rnbd_clt_resize_dev_attr.attr, 447 &rnbd_clt_remap_device_attr.attr, 448 &rnbd_clt_mapping_path_attr.attr, 449 &rnbd_clt_state_attr.attr, 450 &rnbd_clt_session_attr.attr, 451 &rnbd_clt_access_mode.attr, 452 &rnbd_clt_nr_poll_queues.attr, 453 NULL, 454 }; 455 456 void rnbd_clt_remove_dev_symlink(struct rnbd_clt_dev *dev) 457 { 458 /* 459 * The module unload rnbd_client_exit path is racing with unmapping of 460 * the last single device from the sysfs manually 461 * i.e. rnbd_clt_unmap_dev_store() leading to a sysfs warning because 462 * of sysfs link already was removed already. 463 */ 464 if (dev->blk_symlink_name) { 465 if (try_module_get(THIS_MODULE)) { 466 sysfs_remove_link(rnbd_devs_kobj, dev->blk_symlink_name); 467 module_put(THIS_MODULE); 468 } 469 /* It should be freed always. */ 470 kfree(dev->blk_symlink_name); 471 dev->blk_symlink_name = NULL; 472 } 473 } 474 475 static struct kobj_type rnbd_dev_ktype = { 476 .sysfs_ops = &kobj_sysfs_ops, 477 .default_attrs = rnbd_dev_attrs, 478 }; 479 480 static int rnbd_clt_add_dev_kobj(struct rnbd_clt_dev *dev) 481 { 482 int ret; 483 struct kobject *gd_kobj = &disk_to_dev(dev->gd)->kobj; 484 485 ret = kobject_init_and_add(&dev->kobj, &rnbd_dev_ktype, gd_kobj, "%s", 486 "rnbd"); 487 if (ret) { 488 rnbd_clt_err(dev, "Failed to create device sysfs dir, err: %d\n", 489 ret); 490 kobject_put(&dev->kobj); 491 } 492 kobject_uevent(gd_kobj, KOBJ_ONLINE); 493 494 return ret; 495 } 496 497 static ssize_t rnbd_clt_map_device_show(struct kobject *kobj, 498 struct kobj_attribute *attr, 499 char *page) 500 { 501 return sysfs_emit(page, 502 "Usage: echo \"[dest_port=server port number] sessname=<name of the rtrs session> path=<[srcaddr@]dstaddr> [path=<[srcaddr@]dstaddr>] device_path=<full path on remote side> [access_mode=<ro|rw|migration>] [nr_poll_queues=<number of queues>]\" > %s\n\naddr ::= [ ip:<ipv4> | ip:<ipv6> | gid:<gid> ]\n", 503 attr->attr.name); 504 } 505 506 static int rnbd_clt_get_path_name(struct rnbd_clt_dev *dev, char *buf, 507 size_t len) 508 { 509 int ret; 510 char pathname[NAME_MAX], *s; 511 512 strscpy(pathname, dev->pathname, sizeof(pathname)); 513 while ((s = strchr(pathname, '/'))) 514 s[0] = '!'; 515 516 ret = snprintf(buf, len, "%s@%s", pathname, dev->sess->sessname); 517 if (ret >= len) 518 return -ENAMETOOLONG; 519 520 return 0; 521 } 522 523 static int rnbd_clt_add_dev_symlink(struct rnbd_clt_dev *dev) 524 { 525 struct kobject *gd_kobj = &disk_to_dev(dev->gd)->kobj; 526 int ret, len; 527 528 len = strlen(dev->pathname) + strlen(dev->sess->sessname) + 2; 529 dev->blk_symlink_name = kzalloc(len, GFP_KERNEL); 530 if (!dev->blk_symlink_name) { 531 rnbd_clt_err(dev, "Failed to allocate memory for blk_symlink_name\n"); 532 return -ENOMEM; 533 } 534 535 ret = rnbd_clt_get_path_name(dev, dev->blk_symlink_name, 536 len); 537 if (ret) { 538 rnbd_clt_err(dev, "Failed to get /sys/block symlink path, err: %d\n", 539 ret); 540 goto out_err; 541 } 542 543 ret = sysfs_create_link(rnbd_devs_kobj, gd_kobj, 544 dev->blk_symlink_name); 545 if (ret) { 546 rnbd_clt_err(dev, "Creating /sys/block symlink failed, err: %d\n", 547 ret); 548 goto out_err; 549 } 550 551 return 0; 552 553 out_err: 554 kfree(dev->blk_symlink_name); 555 dev->blk_symlink_name = NULL ; 556 return ret; 557 } 558 559 static ssize_t rnbd_clt_map_device_store(struct kobject *kobj, 560 struct kobj_attribute *attr, 561 const char *buf, size_t count) 562 { 563 struct rnbd_clt_dev *dev; 564 struct rnbd_map_options opt; 565 int ret; 566 char pathname[NAME_MAX]; 567 char sessname[NAME_MAX]; 568 enum rnbd_access_mode access_mode = RNBD_ACCESS_RW; 569 u16 port_nr = RTRS_PORT; 570 u32 nr_poll_queues = 0; 571 572 struct sockaddr_storage *addrs; 573 struct rtrs_addr paths[6]; 574 size_t path_cnt; 575 576 opt.sessname = sessname; 577 opt.paths = paths; 578 opt.path_cnt = &path_cnt; 579 opt.pathname = pathname; 580 opt.dest_port = &port_nr; 581 opt.access_mode = &access_mode; 582 opt.nr_poll_queues = &nr_poll_queues; 583 addrs = kcalloc(ARRAY_SIZE(paths) * 2, sizeof(*addrs), GFP_KERNEL); 584 if (!addrs) 585 return -ENOMEM; 586 587 for (path_cnt = 0; path_cnt < ARRAY_SIZE(paths); path_cnt++) { 588 paths[path_cnt].src = &addrs[path_cnt * 2]; 589 paths[path_cnt].dst = &addrs[path_cnt * 2 + 1]; 590 } 591 592 ret = rnbd_clt_parse_map_options(buf, ARRAY_SIZE(paths), &opt); 593 if (ret) 594 goto out; 595 596 pr_info("Mapping device %s on session %s, (access_mode: %s, nr_poll_queues: %d)\n", 597 pathname, sessname, 598 rnbd_access_mode_str(access_mode), 599 nr_poll_queues); 600 601 dev = rnbd_clt_map_device(sessname, paths, path_cnt, port_nr, pathname, 602 access_mode, nr_poll_queues); 603 if (IS_ERR(dev)) { 604 ret = PTR_ERR(dev); 605 goto out; 606 } 607 608 ret = rnbd_clt_add_dev_kobj(dev); 609 if (ret) 610 goto unmap_dev; 611 612 ret = rnbd_clt_add_dev_symlink(dev); 613 if (ret) 614 goto unmap_dev; 615 616 kfree(addrs); 617 return count; 618 619 unmap_dev: 620 rnbd_clt_unmap_device(dev, true, NULL); 621 out: 622 kfree(addrs); 623 return ret; 624 } 625 626 static struct kobj_attribute rnbd_clt_map_device_attr = 627 __ATTR(map_device, 0644, 628 rnbd_clt_map_device_show, rnbd_clt_map_device_store); 629 630 static struct attribute *default_attrs[] = { 631 &rnbd_clt_map_device_attr.attr, 632 NULL, 633 }; 634 635 static struct attribute_group default_attr_group = { 636 .attrs = default_attrs, 637 }; 638 639 static const struct attribute_group *default_attr_groups[] = { 640 &default_attr_group, 641 NULL, 642 }; 643 644 int rnbd_clt_create_sysfs_files(void) 645 { 646 int err; 647 648 rnbd_dev_class = class_create(THIS_MODULE, "rnbd-client"); 649 if (IS_ERR(rnbd_dev_class)) 650 return PTR_ERR(rnbd_dev_class); 651 652 rnbd_dev = device_create_with_groups(rnbd_dev_class, NULL, 653 MKDEV(0, 0), NULL, 654 default_attr_groups, "ctl"); 655 if (IS_ERR(rnbd_dev)) { 656 err = PTR_ERR(rnbd_dev); 657 goto cls_destroy; 658 } 659 rnbd_devs_kobj = kobject_create_and_add("devices", &rnbd_dev->kobj); 660 if (!rnbd_devs_kobj) { 661 err = -ENOMEM; 662 goto dev_destroy; 663 } 664 665 return 0; 666 667 dev_destroy: 668 device_destroy(rnbd_dev_class, MKDEV(0, 0)); 669 cls_destroy: 670 class_destroy(rnbd_dev_class); 671 672 return err; 673 } 674 675 void rnbd_clt_destroy_sysfs_files(void) 676 { 677 sysfs_remove_group(&rnbd_dev->kobj, &default_attr_group); 678 kobject_del(rnbd_devs_kobj); 679 kobject_put(rnbd_devs_kobj); 680 device_destroy(rnbd_dev_class, MKDEV(0, 0)); 681 class_destroy(rnbd_dev_class); 682 } 683