1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * linux/drivers/net/netconsole.c 4 * 5 * Copyright (C) 2001 Ingo Molnar <mingo@redhat.com> 6 * 7 * This file contains the implementation of an IRQ-safe, crash-safe 8 * kernel console implementation that outputs kernel messages to the 9 * network. 10 * 11 * Modification history: 12 * 13 * 2001-09-17 started by Ingo Molnar. 14 * 2003-08-11 2.6 port by Matt Mackall 15 * simplified options 16 * generic card hooks 17 * works non-modular 18 * 2003-09-07 rewritten with netpoll api 19 */ 20 21 /**************************************************************** 22 * 23 ****************************************************************/ 24 25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 27 #include <linux/mm.h> 28 #include <linux/init.h> 29 #include <linux/module.h> 30 #include <linux/slab.h> 31 #include <linux/console.h> 32 #include <linux/moduleparam.h> 33 #include <linux/kernel.h> 34 #include <linux/string.h> 35 #include <linux/netpoll.h> 36 #include <linux/inet.h> 37 #include <linux/configfs.h> 38 #include <linux/etherdevice.h> 39 #include <linux/hex.h> 40 #include <linux/u64_stats_sync.h> 41 #include <linux/utsname.h> 42 #include <linux/rtnetlink.h> 43 #include <linux/workqueue.h> 44 45 MODULE_AUTHOR("Matt Mackall <mpm@selenic.com>"); 46 MODULE_DESCRIPTION("Console driver for network interfaces"); 47 MODULE_LICENSE("GPL"); 48 49 #define MAX_PARAM_LENGTH 256 50 #define MAX_EXTRADATA_ENTRY_LEN 256 51 #define MAX_EXTRADATA_VALUE_LEN 200 52 /* The number 3 comes from userdata entry format characters (' ', '=', '\n') */ 53 #define MAX_EXTRADATA_NAME_LEN (MAX_EXTRADATA_ENTRY_LEN - \ 54 MAX_EXTRADATA_VALUE_LEN - 3) 55 #define MAX_USERDATA_ITEMS 256 56 #define MAX_PRINT_CHUNK 1000 57 58 static char config[MAX_PARAM_LENGTH]; 59 module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0); 60 MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]"); 61 62 static bool oops_only; 63 module_param(oops_only, bool, 0600); 64 MODULE_PARM_DESC(oops_only, "Only log oops messages"); 65 66 #define NETCONSOLE_PARAM_TARGET_PREFIX "cmdline" 67 68 #ifndef MODULE 69 static int __init option_setup(char *opt) 70 { 71 strscpy(config, opt, MAX_PARAM_LENGTH); 72 return 1; 73 } 74 __setup("netconsole=", option_setup); 75 #endif /* MODULE */ 76 77 /* Linked list of all configured targets */ 78 static LIST_HEAD(target_list); 79 /* target_cleanup_list is used to track targets that need to be cleaned outside 80 * of target_list_lock. It should be cleaned in the same function it is 81 * populated. 82 */ 83 static LIST_HEAD(target_cleanup_list); 84 85 /* This needs to be a spinlock because write_msg() cannot sleep */ 86 static DEFINE_SPINLOCK(target_list_lock); 87 /* This needs to be a mutex because netpoll_cleanup might sleep */ 88 static DEFINE_MUTEX(target_cleanup_list_lock); 89 90 static struct workqueue_struct *netconsole_wq; 91 92 /* 93 * Console driver for netconsoles. Register only consoles that have 94 * an associated target of the same type. 95 */ 96 static struct console netconsole_ext, netconsole; 97 98 struct netconsole_target_stats { 99 u64_stats_t xmit_drop_count; 100 u64_stats_t enomem_count; 101 struct u64_stats_sync syncp; 102 }; 103 104 enum console_type { 105 CONS_BASIC = BIT(0), 106 CONS_EXTENDED = BIT(1), 107 }; 108 109 /* Features enabled in sysdata. Contrary to userdata, this data is populated by 110 * the kernel. The fields are designed as bitwise flags, allowing multiple 111 * features to be set in sysdata_fields. 112 */ 113 enum sysdata_feature { 114 /* Populate the CPU that sends the message */ 115 SYSDATA_CPU_NR = BIT(0), 116 /* Populate the task name (as in current->comm) in sysdata */ 117 SYSDATA_TASKNAME = BIT(1), 118 /* Kernel release/version as part of sysdata */ 119 SYSDATA_RELEASE = BIT(2), 120 /* Include a per-target message ID as part of sysdata */ 121 SYSDATA_MSGID = BIT(3), 122 /* Sentinel: highest bit position */ 123 MAX_SYSDATA_ITEMS = 4, 124 }; 125 126 enum target_state { 127 STATE_DISABLED, 128 STATE_ENABLED, 129 STATE_DEACTIVATED, 130 }; 131 132 /** 133 * struct netconsole_target - Represents a configured netconsole target. 134 * @list: Links this target into the target_list. 135 * @group: Links us into the configfs subsystem hierarchy. 136 * @userdata_group: Links to the userdata configfs hierarchy 137 * @userdata: Cached, formatted string of append 138 * @userdata_length: String length of userdata. 139 * @sysdata: Cached, formatted string of append 140 * @sysdata_fields: Sysdata features enabled. 141 * @msgcounter: Message sent counter. 142 * @stats: Packet send stats for the target. Used for debugging. 143 * @state: State of the target. 144 * Visible from userspace (read-write). 145 * From a userspace perspective, the target is either enabled or 146 * disabled. Internally, although both STATE_DISABLED and 147 * STATE_DEACTIVATED correspond to inactive targets, the latter is 148 * due to automatic interface state changes and will try 149 * recover automatically, if the interface comes back 150 * online. 151 * Also, other parameters of a target may be modified at 152 * runtime only when it is disabled (state != STATE_ENABLED). 153 * @extended: Denotes whether console is extended or not. 154 * @release: Denotes whether kernel release version should be prepended 155 * to the message. Depends on extended console. 156 * @np: The netpoll structure for this target. 157 * Contains the other userspace visible parameters: 158 * dev_name (read-write) 159 * local_port (read-write) 160 * remote_port (read-write) 161 * local_ip (read-write) 162 * remote_ip (read-write) 163 * local_mac (read-only) 164 * remote_mac (read-write) 165 * @buf: The buffer used to send the full msg to the network stack 166 * @resume_wq: Workqueue to resume deactivated target 167 */ 168 struct netconsole_target { 169 struct list_head list; 170 #ifdef CONFIG_NETCONSOLE_DYNAMIC 171 struct config_group group; 172 struct config_group userdata_group; 173 char *userdata; 174 size_t userdata_length; 175 char sysdata[MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS]; 176 177 /* bit-wise with sysdata_feature bits */ 178 u32 sysdata_fields; 179 /* protected by target_list_lock */ 180 u32 msgcounter; 181 #endif 182 struct netconsole_target_stats stats; 183 enum target_state state; 184 bool extended; 185 bool release; 186 struct netpoll np; 187 /* protected by target_list_lock */ 188 char buf[MAX_PRINT_CHUNK]; 189 struct work_struct resume_wq; 190 }; 191 192 #ifdef CONFIG_NETCONSOLE_DYNAMIC 193 194 static struct configfs_subsystem netconsole_subsys; 195 static DEFINE_MUTEX(dynamic_netconsole_mutex); 196 197 static int __init dynamic_netconsole_init(void) 198 { 199 config_group_init(&netconsole_subsys.su_group); 200 mutex_init(&netconsole_subsys.su_mutex); 201 return configfs_register_subsystem(&netconsole_subsys); 202 } 203 204 static void __exit dynamic_netconsole_exit(void) 205 { 206 configfs_unregister_subsystem(&netconsole_subsys); 207 } 208 209 /* 210 * Targets that were created by parsing the boot/module option string 211 * do not exist in the configfs hierarchy (and have NULL names) and will 212 * never go away, so make these a no-op for them. 213 */ 214 static void netconsole_target_get(struct netconsole_target *nt) 215 { 216 if (config_item_name(&nt->group.cg_item)) 217 config_group_get(&nt->group); 218 } 219 220 static void netconsole_target_put(struct netconsole_target *nt) 221 { 222 if (config_item_name(&nt->group.cg_item)) 223 config_group_put(&nt->group); 224 } 225 226 static void dynamic_netconsole_mutex_lock(void) 227 { 228 mutex_lock(&dynamic_netconsole_mutex); 229 } 230 231 static void dynamic_netconsole_mutex_unlock(void) 232 { 233 mutex_unlock(&dynamic_netconsole_mutex); 234 } 235 236 #else /* !CONFIG_NETCONSOLE_DYNAMIC */ 237 238 static int __init dynamic_netconsole_init(void) 239 { 240 return 0; 241 } 242 243 static void __exit dynamic_netconsole_exit(void) 244 { 245 } 246 247 /* 248 * No danger of targets going away from under us when dynamic 249 * reconfigurability is off. 250 */ 251 static void netconsole_target_get(struct netconsole_target *nt) 252 { 253 } 254 255 static void netconsole_target_put(struct netconsole_target *nt) 256 { 257 } 258 259 static void populate_configfs_item(struct netconsole_target *nt, 260 int cmdline_count) 261 { 262 } 263 264 static void dynamic_netconsole_mutex_lock(void) 265 { 266 } 267 268 static void dynamic_netconsole_mutex_unlock(void) 269 { 270 } 271 272 #endif /* CONFIG_NETCONSOLE_DYNAMIC */ 273 274 /* Check if the target was bound by mac address. */ 275 static bool bound_by_mac(struct netconsole_target *nt) 276 { 277 return is_valid_ether_addr(nt->np.dev_mac); 278 } 279 280 /* Attempts to resume logging to a deactivated target. */ 281 static void resume_target(struct netconsole_target *nt) 282 { 283 if (netpoll_setup(&nt->np)) { 284 /* netpoll fails setup once, do not try again. */ 285 nt->state = STATE_DISABLED; 286 return; 287 } 288 289 nt->state = STATE_ENABLED; 290 pr_info("network logging resumed on interface %s\n", nt->np.dev_name); 291 } 292 293 /* Checks if a deactivated target matches a device. */ 294 static bool deactivated_target_match(struct netconsole_target *nt, 295 struct net_device *ndev) 296 { 297 if (nt->state != STATE_DEACTIVATED) 298 return false; 299 300 if (bound_by_mac(nt)) 301 return !memcmp(nt->np.dev_mac, ndev->dev_addr, ETH_ALEN); 302 return !strncmp(nt->np.dev_name, ndev->name, IFNAMSIZ); 303 } 304 305 /* Process work scheduled for target resume. */ 306 static void process_resume_target(struct work_struct *work) 307 { 308 struct netconsole_target *nt; 309 unsigned long flags; 310 311 nt = container_of(work, struct netconsole_target, resume_wq); 312 313 dynamic_netconsole_mutex_lock(); 314 315 spin_lock_irqsave(&target_list_lock, flags); 316 /* Check if target is still deactivated as it may have been disabled 317 * while resume was being scheduled. 318 */ 319 if (nt->state != STATE_DEACTIVATED) { 320 spin_unlock_irqrestore(&target_list_lock, flags); 321 goto out_unlock; 322 } 323 324 /* resume_target is IRQ unsafe, remove target from 325 * target_list in order to resume it with IRQ enabled. 326 */ 327 list_del_init(&nt->list); 328 spin_unlock_irqrestore(&target_list_lock, flags); 329 330 resume_target(nt); 331 332 /* At this point the target is either enabled or disabled and 333 * was cleaned up before getting deactivated. Either way, add it 334 * back to target list. 335 */ 336 spin_lock_irqsave(&target_list_lock, flags); 337 list_add(&nt->list, &target_list); 338 spin_unlock_irqrestore(&target_list_lock, flags); 339 340 out_unlock: 341 dynamic_netconsole_mutex_unlock(); 342 } 343 344 /* Allocate and initialize with defaults. 345 * Note that these targets get their config_item fields zeroed-out. 346 */ 347 static struct netconsole_target *alloc_and_init(void) 348 { 349 struct netconsole_target *nt; 350 351 nt = kzalloc_obj(*nt); 352 if (!nt) 353 return nt; 354 355 if (IS_ENABLED(CONFIG_NETCONSOLE_EXTENDED_LOG)) 356 nt->extended = true; 357 if (IS_ENABLED(CONFIG_NETCONSOLE_PREPEND_RELEASE)) 358 nt->release = true; 359 360 nt->np.name = "netconsole"; 361 strscpy(nt->np.dev_name, "eth0", IFNAMSIZ); 362 nt->np.local_port = 6665; 363 nt->np.remote_port = 6666; 364 eth_broadcast_addr(nt->np.remote_mac); 365 nt->state = STATE_DISABLED; 366 INIT_WORK(&nt->resume_wq, process_resume_target); 367 368 return nt; 369 } 370 371 /* Clean up every target in the cleanup_list and move the clean targets back to 372 * the main target_list. 373 */ 374 static void netconsole_process_cleanups_core(void) 375 { 376 struct netconsole_target *nt, *tmp; 377 unsigned long flags; 378 379 /* The cleanup needs RTNL locked */ 380 ASSERT_RTNL(); 381 382 mutex_lock(&target_cleanup_list_lock); 383 list_for_each_entry_safe(nt, tmp, &target_cleanup_list, list) { 384 /* all entries in the cleanup_list needs to be disabled */ 385 WARN_ON_ONCE(nt->state == STATE_ENABLED); 386 do_netpoll_cleanup(&nt->np); 387 if (bound_by_mac(nt)) 388 memset(&nt->np.dev_name, 0, IFNAMSIZ); 389 /* moved the cleaned target to target_list. Need to hold both 390 * locks 391 */ 392 spin_lock_irqsave(&target_list_lock, flags); 393 list_move(&nt->list, &target_list); 394 spin_unlock_irqrestore(&target_list_lock, flags); 395 } 396 WARN_ON_ONCE(!list_empty(&target_cleanup_list)); 397 mutex_unlock(&target_cleanup_list_lock); 398 } 399 400 static void netconsole_print_banner(struct netpoll *np) 401 { 402 np_info(np, "local port %d\n", np->local_port); 403 if (np->ipv6) 404 np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6); 405 else 406 np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip); 407 np_info(np, "interface name '%s'\n", np->dev_name); 408 np_info(np, "local ethernet address '%pM'\n", np->dev_mac); 409 np_info(np, "remote port %d\n", np->remote_port); 410 if (np->ipv6) 411 np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6); 412 else 413 np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip); 414 np_info(np, "remote ethernet address %pM\n", np->remote_mac); 415 } 416 417 /* Parse the string and populate the `inet_addr` union. Return 0 if IPv4 is 418 * populated, 1 if IPv6 is populated, and -1 upon failure. 419 */ 420 static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr) 421 { 422 const char *end = NULL; 423 int len; 424 425 len = strlen(str); 426 if (!len) 427 return -1; 428 429 if (str[len - 1] == '\n') 430 len -= 1; 431 432 if (in4_pton(str, len, (void *)addr, -1, &end) > 0 && 433 (!end || *end == 0 || *end == '\n')) 434 return 0; 435 436 if (IS_ENABLED(CONFIG_IPV6) && 437 in6_pton(str, len, (void *)addr, -1, &end) > 0 && 438 (!end || *end == 0 || *end == '\n')) 439 return 1; 440 441 return -1; 442 } 443 444 #ifdef CONFIG_NETCONSOLE_DYNAMIC 445 446 /* 447 * Our subsystem hierarchy is: 448 * 449 * /sys/kernel/config/netconsole/ 450 * | 451 * <target>/ 452 * | enabled 453 * | release 454 * | dev_name 455 * | local_port 456 * | remote_port 457 * | local_ip 458 * | remote_ip 459 * | local_mac 460 * | remote_mac 461 * | transmit_errors 462 * | userdata/ 463 * | <key>/ 464 * | value 465 * | ... 466 * | 467 * <target>/... 468 */ 469 470 static struct netconsole_target *to_target(struct config_item *item) 471 { 472 struct config_group *cfg_group; 473 474 cfg_group = to_config_group(item); 475 if (!cfg_group) 476 return NULL; 477 return container_of(to_config_group(item), 478 struct netconsole_target, group); 479 } 480 481 /* Do the list cleanup with the rtnl lock hold. rtnl lock is necessary because 482 * netdev might be cleaned-up by calling __netpoll_cleanup(), 483 */ 484 static void netconsole_process_cleanups(void) 485 { 486 /* rtnl lock is called here, because it has precedence over 487 * target_cleanup_list_lock mutex and target_cleanup_list 488 */ 489 rtnl_lock(); 490 netconsole_process_cleanups_core(); 491 rtnl_unlock(); 492 } 493 494 /* Get rid of possible trailing newline, returning the new length */ 495 static void trim_newline(char *s, size_t maxlen) 496 { 497 size_t len; 498 499 len = strnlen(s, maxlen); 500 if (s[len - 1] == '\n') 501 s[len - 1] = '\0'; 502 } 503 504 /* 505 * Attribute operations for netconsole_target. 506 */ 507 508 static ssize_t enabled_show(struct config_item *item, char *buf) 509 { 510 return sysfs_emit(buf, "%d\n", to_target(item)->state == STATE_ENABLED); 511 } 512 513 static ssize_t extended_show(struct config_item *item, char *buf) 514 { 515 return sysfs_emit(buf, "%d\n", to_target(item)->extended); 516 } 517 518 static ssize_t release_show(struct config_item *item, char *buf) 519 { 520 return sysfs_emit(buf, "%d\n", to_target(item)->release); 521 } 522 523 static ssize_t dev_name_show(struct config_item *item, char *buf) 524 { 525 return sysfs_emit(buf, "%s\n", to_target(item)->np.dev_name); 526 } 527 528 static ssize_t local_port_show(struct config_item *item, char *buf) 529 { 530 return sysfs_emit(buf, "%d\n", to_target(item)->np.local_port); 531 } 532 533 static ssize_t remote_port_show(struct config_item *item, char *buf) 534 { 535 return sysfs_emit(buf, "%d\n", to_target(item)->np.remote_port); 536 } 537 538 static ssize_t local_ip_show(struct config_item *item, char *buf) 539 { 540 struct netconsole_target *nt = to_target(item); 541 542 if (nt->np.ipv6) 543 return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6); 544 else 545 return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip); 546 } 547 548 static ssize_t remote_ip_show(struct config_item *item, char *buf) 549 { 550 struct netconsole_target *nt = to_target(item); 551 552 if (nt->np.ipv6) 553 return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6); 554 else 555 return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip); 556 } 557 558 static ssize_t local_mac_show(struct config_item *item, char *buf) 559 { 560 struct net_device *dev = to_target(item)->np.dev; 561 static const u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 562 563 return sysfs_emit(buf, "%pM\n", dev ? dev->dev_addr : bcast); 564 } 565 566 static ssize_t remote_mac_show(struct config_item *item, char *buf) 567 { 568 return sysfs_emit(buf, "%pM\n", to_target(item)->np.remote_mac); 569 } 570 571 static ssize_t transmit_errors_show(struct config_item *item, char *buf) 572 { 573 struct netconsole_target *nt = to_target(item); 574 u64 xmit_drop_count, enomem_count; 575 unsigned int start; 576 577 do { 578 start = u64_stats_fetch_begin(&nt->stats.syncp); 579 xmit_drop_count = u64_stats_read(&nt->stats.xmit_drop_count); 580 enomem_count = u64_stats_read(&nt->stats.enomem_count); 581 } while (u64_stats_fetch_retry(&nt->stats.syncp, start)); 582 583 return sysfs_emit(buf, "%llu\n", xmit_drop_count + enomem_count); 584 } 585 586 /* configfs helper to display if cpu_nr sysdata feature is enabled */ 587 static ssize_t sysdata_cpu_nr_enabled_show(struct config_item *item, char *buf) 588 { 589 struct netconsole_target *nt = to_target(item->ci_parent); 590 bool cpu_nr_enabled; 591 592 dynamic_netconsole_mutex_lock(); 593 cpu_nr_enabled = !!(nt->sysdata_fields & SYSDATA_CPU_NR); 594 dynamic_netconsole_mutex_unlock(); 595 596 return sysfs_emit(buf, "%d\n", cpu_nr_enabled); 597 } 598 599 /* configfs helper to display if taskname sysdata feature is enabled */ 600 static ssize_t sysdata_taskname_enabled_show(struct config_item *item, 601 char *buf) 602 { 603 struct netconsole_target *nt = to_target(item->ci_parent); 604 bool taskname_enabled; 605 606 dynamic_netconsole_mutex_lock(); 607 taskname_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME); 608 dynamic_netconsole_mutex_unlock(); 609 610 return sysfs_emit(buf, "%d\n", taskname_enabled); 611 } 612 613 static ssize_t sysdata_release_enabled_show(struct config_item *item, 614 char *buf) 615 { 616 struct netconsole_target *nt = to_target(item->ci_parent); 617 bool release_enabled; 618 619 dynamic_netconsole_mutex_lock(); 620 release_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME); 621 dynamic_netconsole_mutex_unlock(); 622 623 return sysfs_emit(buf, "%d\n", release_enabled); 624 } 625 626 /* Iterate in the list of target, and make sure we don't have any console 627 * register without targets of the same type 628 */ 629 static void unregister_netcons_consoles(void) 630 { 631 struct netconsole_target *nt; 632 u32 console_type_needed = 0; 633 unsigned long flags; 634 635 spin_lock_irqsave(&target_list_lock, flags); 636 list_for_each_entry(nt, &target_list, list) { 637 if (nt->extended) 638 console_type_needed |= CONS_EXTENDED; 639 else 640 console_type_needed |= CONS_BASIC; 641 } 642 spin_unlock_irqrestore(&target_list_lock, flags); 643 644 if (!(console_type_needed & CONS_EXTENDED) && 645 console_is_registered(&netconsole_ext)) 646 unregister_console(&netconsole_ext); 647 648 if (!(console_type_needed & CONS_BASIC) && 649 console_is_registered(&netconsole)) 650 unregister_console(&netconsole); 651 } 652 653 static ssize_t sysdata_msgid_enabled_show(struct config_item *item, 654 char *buf) 655 { 656 struct netconsole_target *nt = to_target(item->ci_parent); 657 bool msgid_enabled; 658 659 dynamic_netconsole_mutex_lock(); 660 msgid_enabled = !!(nt->sysdata_fields & SYSDATA_MSGID); 661 dynamic_netconsole_mutex_unlock(); 662 663 return sysfs_emit(buf, "%d\n", msgid_enabled); 664 } 665 666 /* 667 * This one is special -- targets created through the configfs interface 668 * are not enabled (and the corresponding netpoll activated) by default. 669 * The user is expected to set the desired parameters first (which 670 * would enable him to dynamically add new netpoll targets for new 671 * network interfaces as and when they come up). 672 */ 673 static ssize_t enabled_store(struct config_item *item, 674 const char *buf, size_t count) 675 { 676 struct netconsole_target *nt = to_target(item); 677 bool enabled, current_enabled; 678 unsigned long flags; 679 ssize_t ret; 680 681 dynamic_netconsole_mutex_lock(); 682 ret = kstrtobool(buf, &enabled); 683 if (ret) 684 goto out_unlock; 685 686 /* When the user explicitly enables or disables a target that is 687 * currently deactivated, reset its state to disabled. The DEACTIVATED 688 * state only tracks interface-driven deactivation and should _not_ 689 * persist when the user manually changes the target's enabled state. 690 */ 691 if (nt->state == STATE_DEACTIVATED) 692 nt->state = STATE_DISABLED; 693 694 ret = -EINVAL; 695 current_enabled = nt->state == STATE_ENABLED; 696 if (enabled == current_enabled) { 697 pr_info("network logging has already %s\n", 698 current_enabled ? "started" : "stopped"); 699 goto out_unlock; 700 } 701 702 if (enabled) { /* true */ 703 if (nt->release && !nt->extended) { 704 pr_err("Not enabling netconsole. Release feature requires extended log message"); 705 goto out_unlock; 706 } 707 708 if (nt->extended && !console_is_registered(&netconsole_ext)) { 709 netconsole_ext.flags |= CON_ENABLED; 710 register_console(&netconsole_ext); 711 } 712 713 /* User might be enabling the basic format target for the very 714 * first time, make sure the console is registered. 715 */ 716 if (!nt->extended && !console_is_registered(&netconsole)) { 717 netconsole.flags |= CON_ENABLED; 718 register_console(&netconsole); 719 } 720 721 /* 722 * Skip netconsole_parser_cmdline() -- all the attributes are 723 * already configured via configfs. Just print them out. 724 */ 725 netconsole_print_banner(&nt->np); 726 727 ret = netpoll_setup(&nt->np); 728 if (ret) 729 goto out_unlock; 730 731 nt->state = STATE_ENABLED; 732 pr_info("network logging started\n"); 733 } else { /* false */ 734 /* We need to disable the netconsole before cleaning it up 735 * otherwise we might end up in write_msg() with 736 * nt->np.dev == NULL and nt->state == STATE_ENABLED 737 */ 738 mutex_lock(&target_cleanup_list_lock); 739 spin_lock_irqsave(&target_list_lock, flags); 740 nt->state = STATE_DISABLED; 741 /* Remove the target from the list, while holding 742 * target_list_lock 743 */ 744 list_move(&nt->list, &target_cleanup_list); 745 spin_unlock_irqrestore(&target_list_lock, flags); 746 mutex_unlock(&target_cleanup_list_lock); 747 /* Unregister consoles, whose the last target of that type got 748 * disabled. 749 */ 750 unregister_netcons_consoles(); 751 } 752 753 ret = strnlen(buf, count); 754 /* Deferred cleanup */ 755 netconsole_process_cleanups(); 756 out_unlock: 757 dynamic_netconsole_mutex_unlock(); 758 return ret; 759 } 760 761 static ssize_t release_store(struct config_item *item, const char *buf, 762 size_t count) 763 { 764 struct netconsole_target *nt = to_target(item); 765 bool release; 766 ssize_t ret; 767 768 dynamic_netconsole_mutex_lock(); 769 if (nt->state == STATE_ENABLED) { 770 pr_err("target (%s) is enabled, disable to update parameters\n", 771 config_item_name(&nt->group.cg_item)); 772 ret = -EINVAL; 773 goto out_unlock; 774 } 775 776 ret = kstrtobool(buf, &release); 777 if (ret) 778 goto out_unlock; 779 780 nt->release = release; 781 782 ret = strnlen(buf, count); 783 out_unlock: 784 dynamic_netconsole_mutex_unlock(); 785 return ret; 786 } 787 788 static ssize_t extended_store(struct config_item *item, const char *buf, 789 size_t count) 790 { 791 struct netconsole_target *nt = to_target(item); 792 bool extended; 793 ssize_t ret; 794 795 dynamic_netconsole_mutex_lock(); 796 if (nt->state == STATE_ENABLED) { 797 pr_err("target (%s) is enabled, disable to update parameters\n", 798 config_item_name(&nt->group.cg_item)); 799 ret = -EINVAL; 800 goto out_unlock; 801 } 802 803 ret = kstrtobool(buf, &extended); 804 if (ret) 805 goto out_unlock; 806 807 nt->extended = extended; 808 ret = strnlen(buf, count); 809 out_unlock: 810 dynamic_netconsole_mutex_unlock(); 811 return ret; 812 } 813 814 static ssize_t dev_name_store(struct config_item *item, const char *buf, 815 size_t count) 816 { 817 struct netconsole_target *nt = to_target(item); 818 819 dynamic_netconsole_mutex_lock(); 820 if (nt->state == STATE_ENABLED) { 821 pr_err("target (%s) is enabled, disable to update parameters\n", 822 config_item_name(&nt->group.cg_item)); 823 dynamic_netconsole_mutex_unlock(); 824 return -EINVAL; 825 } 826 827 strscpy(nt->np.dev_name, buf, IFNAMSIZ); 828 trim_newline(nt->np.dev_name, IFNAMSIZ); 829 830 dynamic_netconsole_mutex_unlock(); 831 return strnlen(buf, count); 832 } 833 834 static ssize_t local_port_store(struct config_item *item, const char *buf, 835 size_t count) 836 { 837 struct netconsole_target *nt = to_target(item); 838 ssize_t ret = -EINVAL; 839 840 dynamic_netconsole_mutex_lock(); 841 if (nt->state == STATE_ENABLED) { 842 pr_err("target (%s) is enabled, disable to update parameters\n", 843 config_item_name(&nt->group.cg_item)); 844 goto out_unlock; 845 } 846 847 ret = kstrtou16(buf, 10, &nt->np.local_port); 848 if (ret < 0) 849 goto out_unlock; 850 ret = strnlen(buf, count); 851 out_unlock: 852 dynamic_netconsole_mutex_unlock(); 853 return ret; 854 } 855 856 static ssize_t remote_port_store(struct config_item *item, 857 const char *buf, size_t count) 858 { 859 struct netconsole_target *nt = to_target(item); 860 ssize_t ret = -EINVAL; 861 862 dynamic_netconsole_mutex_lock(); 863 if (nt->state == STATE_ENABLED) { 864 pr_err("target (%s) is enabled, disable to update parameters\n", 865 config_item_name(&nt->group.cg_item)); 866 goto out_unlock; 867 } 868 869 ret = kstrtou16(buf, 10, &nt->np.remote_port); 870 if (ret < 0) 871 goto out_unlock; 872 ret = strnlen(buf, count); 873 out_unlock: 874 dynamic_netconsole_mutex_unlock(); 875 return ret; 876 } 877 878 static ssize_t local_ip_store(struct config_item *item, const char *buf, 879 size_t count) 880 { 881 struct netconsole_target *nt = to_target(item); 882 ssize_t ret = -EINVAL; 883 int ipv6; 884 885 dynamic_netconsole_mutex_lock(); 886 if (nt->state == STATE_ENABLED) { 887 pr_err("target (%s) is enabled, disable to update parameters\n", 888 config_item_name(&nt->group.cg_item)); 889 goto out_unlock; 890 } 891 892 ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip); 893 if (ipv6 == -1) 894 goto out_unlock; 895 nt->np.ipv6 = !!ipv6; 896 897 ret = strnlen(buf, count); 898 out_unlock: 899 dynamic_netconsole_mutex_unlock(); 900 return ret; 901 } 902 903 static ssize_t remote_ip_store(struct config_item *item, const char *buf, 904 size_t count) 905 { 906 struct netconsole_target *nt = to_target(item); 907 ssize_t ret = -EINVAL; 908 int ipv6; 909 910 dynamic_netconsole_mutex_lock(); 911 if (nt->state == STATE_ENABLED) { 912 pr_err("target (%s) is enabled, disable to update parameters\n", 913 config_item_name(&nt->group.cg_item)); 914 goto out_unlock; 915 } 916 917 ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip); 918 if (ipv6 == -1) 919 goto out_unlock; 920 nt->np.ipv6 = !!ipv6; 921 922 ret = strnlen(buf, count); 923 out_unlock: 924 dynamic_netconsole_mutex_unlock(); 925 return ret; 926 } 927 928 /* Count number of entries we have in userdata. 929 * This is important because userdata only supports MAX_USERDATA_ITEMS 930 * entries. Before enabling any new userdata feature, number of entries needs 931 * to checked for available space. 932 */ 933 static size_t count_userdata_entries(struct netconsole_target *nt) 934 { 935 return list_count_nodes(&nt->userdata_group.cg_children); 936 } 937 938 static ssize_t remote_mac_store(struct config_item *item, const char *buf, 939 size_t count) 940 { 941 struct netconsole_target *nt = to_target(item); 942 u8 remote_mac[ETH_ALEN]; 943 ssize_t ret = -EINVAL; 944 945 dynamic_netconsole_mutex_lock(); 946 if (nt->state == STATE_ENABLED) { 947 pr_err("target (%s) is enabled, disable to update parameters\n", 948 config_item_name(&nt->group.cg_item)); 949 goto out_unlock; 950 } 951 952 if (!mac_pton(buf, remote_mac)) 953 goto out_unlock; 954 if (buf[MAC_ADDR_STR_LEN] && buf[MAC_ADDR_STR_LEN] != '\n') 955 goto out_unlock; 956 memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN); 957 958 ret = strnlen(buf, count); 959 out_unlock: 960 dynamic_netconsole_mutex_unlock(); 961 return ret; 962 } 963 964 struct userdatum { 965 struct config_item item; 966 char value[MAX_EXTRADATA_VALUE_LEN]; 967 }; 968 969 static struct userdatum *to_userdatum(struct config_item *item) 970 { 971 return container_of(item, struct userdatum, item); 972 } 973 974 struct userdata { 975 struct config_group group; 976 }; 977 978 static struct userdata *to_userdata(struct config_item *item) 979 { 980 return container_of(to_config_group(item), struct userdata, group); 981 } 982 983 static struct netconsole_target *userdata_to_target(struct userdata *ud) 984 { 985 struct config_group *netconsole_group; 986 987 netconsole_group = to_config_group(ud->group.cg_item.ci_parent); 988 return to_target(&netconsole_group->cg_item); 989 } 990 991 static ssize_t userdatum_value_show(struct config_item *item, char *buf) 992 { 993 return sysfs_emit(buf, "%s\n", &(to_userdatum(item)->value[0])); 994 } 995 996 /* Navigate configfs and calculate the lentgh of the formatted string 997 * representing userdata. 998 * Must be called holding netconsole_subsys.su_mutex 999 */ 1000 static int calc_userdata_len(struct netconsole_target *nt) 1001 { 1002 struct userdatum *udm_item; 1003 struct config_item *item; 1004 struct list_head *entry; 1005 int len = 0; 1006 1007 list_for_each(entry, &nt->userdata_group.cg_children) { 1008 item = container_of(entry, struct config_item, ci_entry); 1009 udm_item = to_userdatum(item); 1010 /* Skip userdata with no value set */ 1011 if (udm_item->value[0]) { 1012 len += snprintf(NULL, 0, " %s=%s\n", item->ci_name, 1013 udm_item->value); 1014 } 1015 } 1016 return len; 1017 } 1018 1019 static int update_userdata(struct netconsole_target *nt) 1020 { 1021 struct userdatum *udm_item; 1022 struct config_item *item; 1023 struct list_head *entry; 1024 char *old_buf = NULL; 1025 char *new_buf = NULL; 1026 unsigned long flags; 1027 int offset = 0; 1028 int len; 1029 1030 /* Calculate required buffer size */ 1031 len = calc_userdata_len(nt); 1032 1033 if (WARN_ON_ONCE(len > MAX_EXTRADATA_ENTRY_LEN * MAX_USERDATA_ITEMS)) 1034 return -ENOSPC; 1035 1036 /* Allocate new buffer */ 1037 if (len) { 1038 new_buf = kmalloc(len + 1, GFP_KERNEL); 1039 if (!new_buf) 1040 return -ENOMEM; 1041 } 1042 1043 /* Write userdata to new buffer */ 1044 list_for_each(entry, &nt->userdata_group.cg_children) { 1045 item = container_of(entry, struct config_item, ci_entry); 1046 udm_item = to_userdatum(item); 1047 /* Skip userdata with no value set */ 1048 if (udm_item->value[0]) { 1049 offset += scnprintf(&new_buf[offset], len + 1 - offset, 1050 " %s=%s\n", item->ci_name, 1051 udm_item->value); 1052 } 1053 } 1054 1055 WARN_ON_ONCE(offset != len); 1056 1057 /* Switch to new buffer and free old buffer */ 1058 spin_lock_irqsave(&target_list_lock, flags); 1059 old_buf = nt->userdata; 1060 nt->userdata = new_buf; 1061 nt->userdata_length = offset; 1062 spin_unlock_irqrestore(&target_list_lock, flags); 1063 1064 kfree(old_buf); 1065 1066 return 0; 1067 } 1068 1069 static ssize_t userdatum_value_store(struct config_item *item, const char *buf, 1070 size_t count) 1071 { 1072 struct userdatum *udm = to_userdatum(item); 1073 struct netconsole_target *nt; 1074 struct userdata *ud; 1075 ssize_t ret; 1076 1077 if (count > MAX_EXTRADATA_VALUE_LEN) 1078 return -EMSGSIZE; 1079 1080 mutex_lock(&netconsole_subsys.su_mutex); 1081 dynamic_netconsole_mutex_lock(); 1082 1083 ret = strscpy(udm->value, buf, sizeof(udm->value)); 1084 if (ret < 0) 1085 goto out_unlock; 1086 trim_newline(udm->value, sizeof(udm->value)); 1087 1088 ud = to_userdata(item->ci_parent); 1089 nt = userdata_to_target(ud); 1090 ret = update_userdata(nt); 1091 if (ret < 0) 1092 goto out_unlock; 1093 ret = count; 1094 out_unlock: 1095 dynamic_netconsole_mutex_unlock(); 1096 mutex_unlock(&netconsole_subsys.su_mutex); 1097 return ret; 1098 } 1099 1100 /* disable_sysdata_feature - Disable sysdata feature and clean sysdata 1101 * @nt: target that is disabling the feature 1102 * @feature: feature being disabled 1103 */ 1104 static void disable_sysdata_feature(struct netconsole_target *nt, 1105 enum sysdata_feature feature) 1106 { 1107 nt->sysdata_fields &= ~feature; 1108 nt->sysdata[0] = 0; 1109 } 1110 1111 static ssize_t sysdata_msgid_enabled_store(struct config_item *item, 1112 const char *buf, size_t count) 1113 { 1114 struct netconsole_target *nt = to_target(item->ci_parent); 1115 bool msgid_enabled, curr; 1116 ssize_t ret; 1117 1118 ret = kstrtobool(buf, &msgid_enabled); 1119 if (ret) 1120 return ret; 1121 1122 mutex_lock(&netconsole_subsys.su_mutex); 1123 dynamic_netconsole_mutex_lock(); 1124 curr = !!(nt->sysdata_fields & SYSDATA_MSGID); 1125 if (msgid_enabled == curr) 1126 goto unlock_ok; 1127 1128 if (msgid_enabled) 1129 nt->sysdata_fields |= SYSDATA_MSGID; 1130 else 1131 disable_sysdata_feature(nt, SYSDATA_MSGID); 1132 1133 unlock_ok: 1134 ret = strnlen(buf, count); 1135 dynamic_netconsole_mutex_unlock(); 1136 mutex_unlock(&netconsole_subsys.su_mutex); 1137 return ret; 1138 } 1139 1140 static ssize_t sysdata_release_enabled_store(struct config_item *item, 1141 const char *buf, size_t count) 1142 { 1143 struct netconsole_target *nt = to_target(item->ci_parent); 1144 bool release_enabled, curr; 1145 ssize_t ret; 1146 1147 ret = kstrtobool(buf, &release_enabled); 1148 if (ret) 1149 return ret; 1150 1151 mutex_lock(&netconsole_subsys.su_mutex); 1152 dynamic_netconsole_mutex_lock(); 1153 curr = !!(nt->sysdata_fields & SYSDATA_RELEASE); 1154 if (release_enabled == curr) 1155 goto unlock_ok; 1156 1157 if (release_enabled) 1158 nt->sysdata_fields |= SYSDATA_RELEASE; 1159 else 1160 disable_sysdata_feature(nt, SYSDATA_RELEASE); 1161 1162 unlock_ok: 1163 ret = strnlen(buf, count); 1164 dynamic_netconsole_mutex_unlock(); 1165 mutex_unlock(&netconsole_subsys.su_mutex); 1166 return ret; 1167 } 1168 1169 static ssize_t sysdata_taskname_enabled_store(struct config_item *item, 1170 const char *buf, size_t count) 1171 { 1172 struct netconsole_target *nt = to_target(item->ci_parent); 1173 bool taskname_enabled, curr; 1174 ssize_t ret; 1175 1176 ret = kstrtobool(buf, &taskname_enabled); 1177 if (ret) 1178 return ret; 1179 1180 mutex_lock(&netconsole_subsys.su_mutex); 1181 dynamic_netconsole_mutex_lock(); 1182 curr = !!(nt->sysdata_fields & SYSDATA_TASKNAME); 1183 if (taskname_enabled == curr) 1184 goto unlock_ok; 1185 1186 if (taskname_enabled) 1187 nt->sysdata_fields |= SYSDATA_TASKNAME; 1188 else 1189 disable_sysdata_feature(nt, SYSDATA_TASKNAME); 1190 1191 unlock_ok: 1192 ret = strnlen(buf, count); 1193 dynamic_netconsole_mutex_unlock(); 1194 mutex_unlock(&netconsole_subsys.su_mutex); 1195 return ret; 1196 } 1197 1198 /* configfs helper to sysdata cpu_nr feature */ 1199 static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item, 1200 const char *buf, size_t count) 1201 { 1202 struct netconsole_target *nt = to_target(item->ci_parent); 1203 bool cpu_nr_enabled, curr; 1204 ssize_t ret; 1205 1206 ret = kstrtobool(buf, &cpu_nr_enabled); 1207 if (ret) 1208 return ret; 1209 1210 mutex_lock(&netconsole_subsys.su_mutex); 1211 dynamic_netconsole_mutex_lock(); 1212 curr = !!(nt->sysdata_fields & SYSDATA_CPU_NR); 1213 if (cpu_nr_enabled == curr) 1214 /* no change requested */ 1215 goto unlock_ok; 1216 1217 if (cpu_nr_enabled) 1218 nt->sysdata_fields |= SYSDATA_CPU_NR; 1219 else 1220 /* This is special because sysdata might have remaining data 1221 * from previous sysdata, and it needs to be cleaned. 1222 */ 1223 disable_sysdata_feature(nt, SYSDATA_CPU_NR); 1224 1225 unlock_ok: 1226 ret = strnlen(buf, count); 1227 dynamic_netconsole_mutex_unlock(); 1228 mutex_unlock(&netconsole_subsys.su_mutex); 1229 return ret; 1230 } 1231 1232 CONFIGFS_ATTR(userdatum_, value); 1233 CONFIGFS_ATTR(sysdata_, cpu_nr_enabled); 1234 CONFIGFS_ATTR(sysdata_, taskname_enabled); 1235 CONFIGFS_ATTR(sysdata_, release_enabled); 1236 CONFIGFS_ATTR(sysdata_, msgid_enabled); 1237 1238 static struct configfs_attribute *userdatum_attrs[] = { 1239 &userdatum_attr_value, 1240 NULL, 1241 }; 1242 1243 static void userdatum_release(struct config_item *item) 1244 { 1245 kfree(to_userdatum(item)); 1246 } 1247 1248 static struct configfs_item_operations userdatum_ops = { 1249 .release = userdatum_release, 1250 }; 1251 1252 static const struct config_item_type userdatum_type = { 1253 .ct_item_ops = &userdatum_ops, 1254 .ct_attrs = userdatum_attrs, 1255 .ct_owner = THIS_MODULE, 1256 }; 1257 1258 static struct config_item *userdatum_make_item(struct config_group *group, 1259 const char *name) 1260 { 1261 struct netconsole_target *nt; 1262 struct userdatum *udm; 1263 struct userdata *ud; 1264 1265 if (strlen(name) > MAX_EXTRADATA_NAME_LEN) 1266 return ERR_PTR(-ENAMETOOLONG); 1267 1268 ud = to_userdata(&group->cg_item); 1269 nt = userdata_to_target(ud); 1270 if (count_userdata_entries(nt) >= MAX_USERDATA_ITEMS) 1271 return ERR_PTR(-ENOSPC); 1272 1273 udm = kzalloc_obj(*udm); 1274 if (!udm) 1275 return ERR_PTR(-ENOMEM); 1276 1277 config_item_init_type_name(&udm->item, name, &userdatum_type); 1278 return &udm->item; 1279 } 1280 1281 static void userdatum_drop(struct config_group *group, struct config_item *item) 1282 { 1283 struct netconsole_target *nt; 1284 struct userdata *ud; 1285 1286 ud = to_userdata(&group->cg_item); 1287 nt = userdata_to_target(ud); 1288 1289 dynamic_netconsole_mutex_lock(); 1290 update_userdata(nt); 1291 config_item_put(item); 1292 dynamic_netconsole_mutex_unlock(); 1293 } 1294 1295 static struct configfs_attribute *userdata_attrs[] = { 1296 &sysdata_attr_cpu_nr_enabled, 1297 &sysdata_attr_taskname_enabled, 1298 &sysdata_attr_release_enabled, 1299 &sysdata_attr_msgid_enabled, 1300 NULL, 1301 }; 1302 1303 static struct configfs_group_operations userdata_ops = { 1304 .make_item = userdatum_make_item, 1305 .drop_item = userdatum_drop, 1306 }; 1307 1308 static const struct config_item_type userdata_type = { 1309 .ct_item_ops = &userdatum_ops, 1310 .ct_group_ops = &userdata_ops, 1311 .ct_attrs = userdata_attrs, 1312 .ct_owner = THIS_MODULE, 1313 }; 1314 1315 CONFIGFS_ATTR(, enabled); 1316 CONFIGFS_ATTR(, extended); 1317 CONFIGFS_ATTR(, dev_name); 1318 CONFIGFS_ATTR(, local_port); 1319 CONFIGFS_ATTR(, remote_port); 1320 CONFIGFS_ATTR(, local_ip); 1321 CONFIGFS_ATTR(, remote_ip); 1322 CONFIGFS_ATTR_RO(, local_mac); 1323 CONFIGFS_ATTR(, remote_mac); 1324 CONFIGFS_ATTR(, release); 1325 CONFIGFS_ATTR_RO(, transmit_errors); 1326 1327 static struct configfs_attribute *netconsole_target_attrs[] = { 1328 &attr_enabled, 1329 &attr_extended, 1330 &attr_release, 1331 &attr_dev_name, 1332 &attr_local_port, 1333 &attr_remote_port, 1334 &attr_local_ip, 1335 &attr_remote_ip, 1336 &attr_local_mac, 1337 &attr_remote_mac, 1338 &attr_transmit_errors, 1339 NULL, 1340 }; 1341 1342 /* 1343 * Item operations and type for netconsole_target. 1344 */ 1345 1346 static void netconsole_target_release(struct config_item *item) 1347 { 1348 struct netconsole_target *nt = to_target(item); 1349 1350 kfree(nt->userdata); 1351 kfree(nt); 1352 } 1353 1354 static struct configfs_item_operations netconsole_target_item_ops = { 1355 .release = netconsole_target_release, 1356 }; 1357 1358 static const struct config_item_type netconsole_target_type = { 1359 .ct_attrs = netconsole_target_attrs, 1360 .ct_item_ops = &netconsole_target_item_ops, 1361 .ct_owner = THIS_MODULE, 1362 }; 1363 1364 static void init_target_config_group(struct netconsole_target *nt, 1365 const char *name) 1366 { 1367 config_group_init_type_name(&nt->group, name, &netconsole_target_type); 1368 config_group_init_type_name(&nt->userdata_group, "userdata", 1369 &userdata_type); 1370 configfs_add_default_group(&nt->userdata_group, &nt->group); 1371 } 1372 1373 static struct netconsole_target *find_cmdline_target(const char *name) 1374 { 1375 struct netconsole_target *nt, *ret = NULL; 1376 unsigned long flags; 1377 1378 spin_lock_irqsave(&target_list_lock, flags); 1379 list_for_each_entry(nt, &target_list, list) { 1380 if (!strcmp(nt->group.cg_item.ci_name, name)) { 1381 ret = nt; 1382 break; 1383 } 1384 } 1385 spin_unlock_irqrestore(&target_list_lock, flags); 1386 1387 return ret; 1388 } 1389 1390 /* 1391 * Group operations and type for netconsole_subsys. 1392 */ 1393 1394 static struct config_group *make_netconsole_target(struct config_group *group, 1395 const char *name) 1396 { 1397 struct netconsole_target *nt; 1398 unsigned long flags; 1399 1400 /* Checking if a target by this name was created at boot time. If so, 1401 * attach a configfs entry to that target. This enables dynamic 1402 * control. 1403 */ 1404 if (!strncmp(name, NETCONSOLE_PARAM_TARGET_PREFIX, 1405 strlen(NETCONSOLE_PARAM_TARGET_PREFIX))) { 1406 nt = find_cmdline_target(name); 1407 if (nt) { 1408 init_target_config_group(nt, name); 1409 return &nt->group; 1410 } 1411 } 1412 1413 nt = alloc_and_init(); 1414 if (!nt) 1415 return ERR_PTR(-ENOMEM); 1416 1417 /* Initialize the config_group member */ 1418 init_target_config_group(nt, name); 1419 1420 /* Adding, but it is disabled */ 1421 spin_lock_irqsave(&target_list_lock, flags); 1422 list_add(&nt->list, &target_list); 1423 spin_unlock_irqrestore(&target_list_lock, flags); 1424 1425 return &nt->group; 1426 } 1427 1428 static void drop_netconsole_target(struct config_group *group, 1429 struct config_item *item) 1430 { 1431 struct netconsole_target *nt = to_target(item); 1432 unsigned long flags; 1433 1434 dynamic_netconsole_mutex_lock(); 1435 1436 spin_lock_irqsave(&target_list_lock, flags); 1437 /* Disable deactivated target to prevent races between resume attempt 1438 * and target removal. 1439 */ 1440 if (nt->state == STATE_DEACTIVATED) 1441 nt->state = STATE_DISABLED; 1442 list_del(&nt->list); 1443 spin_unlock_irqrestore(&target_list_lock, flags); 1444 1445 dynamic_netconsole_mutex_unlock(); 1446 1447 /* Now that the target has been marked disabled no further work 1448 * can be scheduled. Existing work will skip as targets are not 1449 * deactivated anymore. Cancel any scheduled resume and wait for 1450 * completion. 1451 */ 1452 cancel_work_sync(&nt->resume_wq); 1453 1454 /* 1455 * The target may have never been enabled, or was manually disabled 1456 * before being removed so netpoll may have already been cleaned up. 1457 */ 1458 if (nt->state == STATE_ENABLED) 1459 netpoll_cleanup(&nt->np); 1460 1461 config_item_put(&nt->group.cg_item); 1462 } 1463 1464 static struct configfs_group_operations netconsole_subsys_group_ops = { 1465 .make_group = make_netconsole_target, 1466 .drop_item = drop_netconsole_target, 1467 }; 1468 1469 static const struct config_item_type netconsole_subsys_type = { 1470 .ct_group_ops = &netconsole_subsys_group_ops, 1471 .ct_owner = THIS_MODULE, 1472 }; 1473 1474 /* The netconsole configfs subsystem */ 1475 static struct configfs_subsystem netconsole_subsys = { 1476 .su_group = { 1477 .cg_item = { 1478 .ci_namebuf = "netconsole", 1479 .ci_type = &netconsole_subsys_type, 1480 }, 1481 }, 1482 }; 1483 1484 static void populate_configfs_item(struct netconsole_target *nt, 1485 int cmdline_count) 1486 { 1487 char target_name[16]; 1488 1489 snprintf(target_name, sizeof(target_name), "%s%d", 1490 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count); 1491 init_target_config_group(nt, target_name); 1492 } 1493 1494 static int sysdata_append_cpu_nr(struct netconsole_target *nt, int offset, 1495 struct nbcon_write_context *wctxt) 1496 { 1497 return scnprintf(&nt->sysdata[offset], 1498 MAX_EXTRADATA_ENTRY_LEN, " cpu=%u\n", 1499 wctxt->cpu); 1500 } 1501 1502 static int sysdata_append_taskname(struct netconsole_target *nt, int offset, 1503 struct nbcon_write_context *wctxt) 1504 { 1505 return scnprintf(&nt->sysdata[offset], 1506 MAX_EXTRADATA_ENTRY_LEN, " taskname=%s\n", 1507 wctxt->comm); 1508 } 1509 1510 static int sysdata_append_release(struct netconsole_target *nt, int offset) 1511 { 1512 return scnprintf(&nt->sysdata[offset], 1513 MAX_EXTRADATA_ENTRY_LEN, " release=%s\n", 1514 init_utsname()->release); 1515 } 1516 1517 static int sysdata_append_msgid(struct netconsole_target *nt, int offset) 1518 { 1519 wrapping_assign_add(nt->msgcounter, 1); 1520 return scnprintf(&nt->sysdata[offset], 1521 MAX_EXTRADATA_ENTRY_LEN, " msgid=%u\n", 1522 nt->msgcounter); 1523 } 1524 1525 /* 1526 * prepare_sysdata - append sysdata in runtime 1527 * @nt: target to send message to 1528 * @wctxt: nbcon write context containing message metadata 1529 */ 1530 static int prepare_sysdata(struct netconsole_target *nt, 1531 struct nbcon_write_context *wctxt) 1532 { 1533 int sysdata_len = 0; 1534 1535 if (!nt->sysdata_fields) 1536 goto out; 1537 1538 if (nt->sysdata_fields & SYSDATA_CPU_NR) 1539 sysdata_len += sysdata_append_cpu_nr(nt, sysdata_len, wctxt); 1540 if (nt->sysdata_fields & SYSDATA_TASKNAME) 1541 sysdata_len += sysdata_append_taskname(nt, sysdata_len, wctxt); 1542 if (nt->sysdata_fields & SYSDATA_RELEASE) 1543 sysdata_len += sysdata_append_release(nt, sysdata_len); 1544 if (nt->sysdata_fields & SYSDATA_MSGID) 1545 sysdata_len += sysdata_append_msgid(nt, sysdata_len); 1546 1547 WARN_ON_ONCE(sysdata_len > 1548 MAX_EXTRADATA_ENTRY_LEN * MAX_SYSDATA_ITEMS); 1549 1550 out: 1551 return sysdata_len; 1552 } 1553 #endif /* CONFIG_NETCONSOLE_DYNAMIC */ 1554 1555 /* Handle network interface device notifications */ 1556 static int netconsole_netdev_event(struct notifier_block *this, 1557 unsigned long event, void *ptr) 1558 { 1559 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 1560 struct netconsole_target *nt, *tmp; 1561 bool stopped = false; 1562 unsigned long flags; 1563 1564 if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER || 1565 event == NETDEV_RELEASE || event == NETDEV_JOIN || 1566 event == NETDEV_REGISTER)) 1567 goto done; 1568 1569 mutex_lock(&target_cleanup_list_lock); 1570 spin_lock_irqsave(&target_list_lock, flags); 1571 list_for_each_entry_safe(nt, tmp, &target_list, list) { 1572 netconsole_target_get(nt); 1573 if (nt->np.dev == dev) { 1574 switch (event) { 1575 case NETDEV_CHANGENAME: 1576 strscpy(nt->np.dev_name, dev->name, IFNAMSIZ); 1577 break; 1578 case NETDEV_RELEASE: 1579 case NETDEV_JOIN: 1580 /* transition target to DISABLED instead of 1581 * DEACTIVATED when (de)enslaving devices as 1582 * their targets should not be automatically 1583 * resumed when the interface is brought up. 1584 */ 1585 nt->state = STATE_DISABLED; 1586 list_move(&nt->list, &target_cleanup_list); 1587 stopped = true; 1588 break; 1589 case NETDEV_UNREGISTER: 1590 nt->state = STATE_DEACTIVATED; 1591 list_move(&nt->list, &target_cleanup_list); 1592 stopped = true; 1593 } 1594 } 1595 if ((event == NETDEV_REGISTER || event == NETDEV_CHANGENAME) && 1596 deactivated_target_match(nt, dev)) 1597 /* Schedule resume on a workqueue as it will attempt 1598 * to UP the device, which can't be done as part of this 1599 * notifier. 1600 */ 1601 queue_work(netconsole_wq, &nt->resume_wq); 1602 netconsole_target_put(nt); 1603 } 1604 spin_unlock_irqrestore(&target_list_lock, flags); 1605 mutex_unlock(&target_cleanup_list_lock); 1606 1607 if (stopped) { 1608 const char *msg = "had an event"; 1609 1610 switch (event) { 1611 case NETDEV_UNREGISTER: 1612 msg = "unregistered"; 1613 break; 1614 case NETDEV_RELEASE: 1615 msg = "released slaves"; 1616 break; 1617 case NETDEV_JOIN: 1618 msg = "is joining a master device"; 1619 break; 1620 } 1621 pr_info("network logging stopped on interface %s as it %s\n", 1622 dev->name, msg); 1623 } 1624 1625 /* Process target_cleanup_list entries. By the end, target_cleanup_list 1626 * should be empty 1627 */ 1628 netconsole_process_cleanups_core(); 1629 1630 done: 1631 return NOTIFY_DONE; 1632 } 1633 1634 static struct notifier_block netconsole_netdev_notifier = { 1635 .notifier_call = netconsole_netdev_event, 1636 }; 1637 1638 /** 1639 * send_udp - Wrapper for netpoll_send_udp that counts errors 1640 * @nt: target to send message to 1641 * @msg: message to send 1642 * @len: length of message 1643 * 1644 * Calls netpoll_send_udp and classifies the return value. If an error 1645 * occurred it increments statistics in nt->stats accordingly. 1646 * Only calls netpoll_send_udp if CONFIG_NETCONSOLE_DYNAMIC is disabled. 1647 */ 1648 static void send_udp(struct netconsole_target *nt, const char *msg, int len) 1649 { 1650 int result = netpoll_send_udp(&nt->np, msg, len); 1651 1652 if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) { 1653 if (result == NET_XMIT_DROP) { 1654 u64_stats_update_begin(&nt->stats.syncp); 1655 u64_stats_inc(&nt->stats.xmit_drop_count); 1656 u64_stats_update_end(&nt->stats.syncp); 1657 } else if (result == -ENOMEM) { 1658 u64_stats_update_begin(&nt->stats.syncp); 1659 u64_stats_inc(&nt->stats.enomem_count); 1660 u64_stats_update_end(&nt->stats.syncp); 1661 } 1662 } 1663 } 1664 1665 static void send_msg_no_fragmentation(struct netconsole_target *nt, 1666 const char *msg, 1667 int msg_len, 1668 int release_len) 1669 { 1670 const char *userdata = NULL; 1671 const char *sysdata = NULL; 1672 const char *release; 1673 1674 #ifdef CONFIG_NETCONSOLE_DYNAMIC 1675 userdata = nt->userdata; 1676 sysdata = nt->sysdata; 1677 #endif 1678 1679 if (release_len) { 1680 release = init_utsname()->release; 1681 1682 scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%.*s", release, 1683 msg_len, msg); 1684 msg_len += release_len; 1685 } else { 1686 memcpy(nt->buf, msg, msg_len); 1687 } 1688 1689 if (userdata) 1690 msg_len += scnprintf(&nt->buf[msg_len], 1691 MAX_PRINT_CHUNK - msg_len, "%s", 1692 userdata); 1693 1694 if (sysdata) 1695 msg_len += scnprintf(&nt->buf[msg_len], 1696 MAX_PRINT_CHUNK - msg_len, "%s", 1697 sysdata); 1698 1699 send_udp(nt, nt->buf, msg_len); 1700 } 1701 1702 static void append_release(char *buf) 1703 { 1704 const char *release; 1705 1706 release = init_utsname()->release; 1707 scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release); 1708 } 1709 1710 static void send_fragmented_body(struct netconsole_target *nt, 1711 const char *msgbody_ptr, int header_len, 1712 int msgbody_len, int sysdata_len) 1713 { 1714 const char *userdata_ptr = NULL; 1715 const char *sysdata_ptr = NULL; 1716 int data_len, data_sent = 0; 1717 int userdata_offset = 0; 1718 int sysdata_offset = 0; 1719 int msgbody_offset = 0; 1720 int userdata_len = 0; 1721 1722 #ifdef CONFIG_NETCONSOLE_DYNAMIC 1723 userdata_ptr = nt->userdata; 1724 sysdata_ptr = nt->sysdata; 1725 userdata_len = nt->userdata_length; 1726 #endif 1727 if (WARN_ON_ONCE(!userdata_ptr && userdata_len != 0)) 1728 return; 1729 1730 if (WARN_ON_ONCE(!sysdata_ptr && sysdata_len != 0)) 1731 return; 1732 1733 /* data_len represents the number of bytes that will be sent. This is 1734 * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple 1735 * packets 1736 */ 1737 data_len = msgbody_len + userdata_len + sysdata_len; 1738 1739 /* In each iteration of the while loop below, we send a packet 1740 * containing the header and a portion of the data. The data is 1741 * composed of three parts: msgbody, userdata, and sysdata. 1742 * We keep track of how many bytes have been sent from each part using 1743 * the *_offset variables. 1744 * We keep track of how many bytes have been sent overall using the 1745 * data_sent variable, which ranges from 0 to the total bytes to be 1746 * sent. 1747 */ 1748 while (data_sent < data_len) { 1749 int userdata_left = userdata_len - userdata_offset; 1750 int sysdata_left = sysdata_len - sysdata_offset; 1751 int msgbody_left = msgbody_len - msgbody_offset; 1752 int buf_offset = 0; 1753 int this_chunk = 0; 1754 1755 /* header is already populated in nt->buf, just append to it */ 1756 buf_offset = header_len; 1757 1758 buf_offset += scnprintf(nt->buf + buf_offset, 1759 MAX_PRINT_CHUNK - buf_offset, 1760 ",ncfrag=%d/%d;", data_sent, 1761 data_len); 1762 1763 /* append msgbody first */ 1764 this_chunk = min(msgbody_left, MAX_PRINT_CHUNK - buf_offset); 1765 memcpy(nt->buf + buf_offset, msgbody_ptr + msgbody_offset, 1766 this_chunk); 1767 msgbody_offset += this_chunk; 1768 buf_offset += this_chunk; 1769 data_sent += this_chunk; 1770 1771 /* after msgbody, append userdata */ 1772 if (userdata_ptr && userdata_left) { 1773 this_chunk = min(userdata_left, 1774 MAX_PRINT_CHUNK - buf_offset); 1775 memcpy(nt->buf + buf_offset, 1776 userdata_ptr + userdata_offset, this_chunk); 1777 userdata_offset += this_chunk; 1778 buf_offset += this_chunk; 1779 data_sent += this_chunk; 1780 } 1781 1782 /* after userdata, append sysdata */ 1783 if (sysdata_ptr && sysdata_left) { 1784 this_chunk = min(sysdata_left, 1785 MAX_PRINT_CHUNK - buf_offset); 1786 memcpy(nt->buf + buf_offset, 1787 sysdata_ptr + sysdata_offset, this_chunk); 1788 sysdata_offset += this_chunk; 1789 buf_offset += this_chunk; 1790 data_sent += this_chunk; 1791 } 1792 1793 /* if all is good, send the packet out */ 1794 if (WARN_ON_ONCE(data_sent > data_len)) 1795 return; 1796 1797 send_udp(nt, nt->buf, buf_offset); 1798 } 1799 } 1800 1801 static void send_msg_fragmented(struct netconsole_target *nt, 1802 const char *msg, 1803 int msg_len, 1804 int release_len, 1805 int sysdata_len) 1806 { 1807 int header_len, msgbody_len; 1808 const char *msgbody; 1809 1810 /* need to insert extra header fields, detect header and msgbody */ 1811 msgbody = memchr(msg, ';', msg_len); 1812 if (WARN_ON_ONCE(!msgbody)) 1813 return; 1814 1815 header_len = msgbody - msg; 1816 msgbody_len = msg_len - header_len - 1; 1817 msgbody++; 1818 1819 /* 1820 * Transfer multiple chunks with the following extra header. 1821 * "ncfrag=<byte-offset>/<total-bytes>" 1822 */ 1823 if (release_len) 1824 append_release(nt->buf); 1825 1826 /* Copy the header into the buffer */ 1827 memcpy(nt->buf + release_len, msg, header_len); 1828 header_len += release_len; 1829 1830 /* for now on, the header will be persisted, and the msgbody 1831 * will be replaced 1832 */ 1833 send_fragmented_body(nt, msgbody, header_len, msgbody_len, 1834 sysdata_len); 1835 } 1836 1837 /** 1838 * send_ext_msg_udp - send extended log message to target 1839 * @nt: target to send message to 1840 * @wctxt: nbcon write context containing message and metadata 1841 * 1842 * Transfer extended log message to @nt. If message is longer than 1843 * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with 1844 * ncfrag header field added to identify them. 1845 */ 1846 static void send_ext_msg_udp(struct netconsole_target *nt, 1847 struct nbcon_write_context *wctxt) 1848 { 1849 int userdata_len = 0; 1850 int release_len = 0; 1851 int sysdata_len = 0; 1852 int len; 1853 1854 #ifdef CONFIG_NETCONSOLE_DYNAMIC 1855 sysdata_len = prepare_sysdata(nt, wctxt); 1856 userdata_len = nt->userdata_length; 1857 #endif 1858 if (nt->release) 1859 release_len = strlen(init_utsname()->release) + 1; 1860 1861 len = wctxt->len + release_len + sysdata_len + userdata_len; 1862 if (len <= MAX_PRINT_CHUNK) 1863 return send_msg_no_fragmentation(nt, wctxt->outbuf, 1864 wctxt->len, release_len); 1865 1866 return send_msg_fragmented(nt, wctxt->outbuf, wctxt->len, release_len, 1867 sysdata_len); 1868 } 1869 1870 static void send_msg_udp(struct netconsole_target *nt, const char *msg, 1871 unsigned int len) 1872 { 1873 const char *tmp = msg; 1874 int frag, left = len; 1875 1876 while (left > 0) { 1877 frag = min(left, MAX_PRINT_CHUNK); 1878 send_udp(nt, tmp, frag); 1879 tmp += frag; 1880 left -= frag; 1881 } 1882 } 1883 1884 /** 1885 * netconsole_write - Generic function to send a msg to all targets 1886 * @wctxt: nbcon write context 1887 * @extended: "true" for extended console mode 1888 * 1889 * Given an nbcon write context, send the message to the netconsole targets 1890 */ 1891 static void netconsole_write(struct nbcon_write_context *wctxt, bool extended) 1892 { 1893 struct netconsole_target *nt; 1894 1895 if (oops_only && !oops_in_progress) 1896 return; 1897 1898 list_for_each_entry(nt, &target_list, list) { 1899 if (nt->extended != extended || nt->state != STATE_ENABLED || 1900 !netif_running(nt->np.dev)) 1901 continue; 1902 1903 /* If nbcon_enter_unsafe() fails, just return given netconsole 1904 * lost the ownership, and iterating over the targets will not 1905 * be able to re-acquire. 1906 */ 1907 if (!nbcon_enter_unsafe(wctxt)) 1908 return; 1909 1910 if (extended) 1911 send_ext_msg_udp(nt, wctxt); 1912 else 1913 send_msg_udp(nt, wctxt->outbuf, wctxt->len); 1914 1915 nbcon_exit_unsafe(wctxt); 1916 } 1917 } 1918 1919 static void netconsole_write_ext(struct console *con __always_unused, 1920 struct nbcon_write_context *wctxt) 1921 { 1922 netconsole_write(wctxt, true); 1923 } 1924 1925 static void netconsole_write_basic(struct console *con __always_unused, 1926 struct nbcon_write_context *wctxt) 1927 { 1928 netconsole_write(wctxt, false); 1929 } 1930 1931 static void netconsole_device_lock(struct console *con __always_unused, 1932 unsigned long *flags) 1933 __acquires(&target_list_lock) 1934 { 1935 spin_lock_irqsave(&target_list_lock, *flags); 1936 } 1937 1938 static void netconsole_device_unlock(struct console *con __always_unused, 1939 unsigned long flags) 1940 __releases(&target_list_lock) 1941 { 1942 spin_unlock_irqrestore(&target_list_lock, flags); 1943 } 1944 1945 static int netconsole_parser_cmdline(struct netpoll *np, char *opt) 1946 { 1947 bool ipversion_set = false; 1948 char *cur = opt; 1949 char *delim; 1950 int ipv6; 1951 1952 if (*cur != '@') { 1953 delim = strchr(cur, '@'); 1954 if (!delim) 1955 goto parse_failed; 1956 *delim = 0; 1957 if (kstrtou16(cur, 10, &np->local_port)) 1958 goto parse_failed; 1959 cur = delim; 1960 } 1961 cur++; 1962 1963 if (*cur != '/') { 1964 ipversion_set = true; 1965 delim = strchr(cur, '/'); 1966 if (!delim) 1967 goto parse_failed; 1968 *delim = 0; 1969 ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip); 1970 if (ipv6 < 0) 1971 goto parse_failed; 1972 else 1973 np->ipv6 = (bool)ipv6; 1974 cur = delim; 1975 } 1976 cur++; 1977 1978 if (*cur != ',') { 1979 /* parse out dev_name or dev_mac */ 1980 delim = strchr(cur, ','); 1981 if (!delim) 1982 goto parse_failed; 1983 *delim = 0; 1984 1985 np->dev_name[0] = '\0'; 1986 eth_broadcast_addr(np->dev_mac); 1987 if (!strchr(cur, ':')) 1988 strscpy(np->dev_name, cur, sizeof(np->dev_name)); 1989 else if (!mac_pton(cur, np->dev_mac)) 1990 goto parse_failed; 1991 1992 cur = delim; 1993 } 1994 cur++; 1995 1996 if (*cur != '@') { 1997 /* dst port */ 1998 delim = strchr(cur, '@'); 1999 if (!delim) 2000 goto parse_failed; 2001 *delim = 0; 2002 if (*cur == ' ' || *cur == '\t') 2003 np_info(np, "warning: whitespace is not allowed\n"); 2004 if (kstrtou16(cur, 10, &np->remote_port)) 2005 goto parse_failed; 2006 cur = delim; 2007 } 2008 cur++; 2009 2010 /* dst ip */ 2011 delim = strchr(cur, '/'); 2012 if (!delim) 2013 goto parse_failed; 2014 *delim = 0; 2015 ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip); 2016 if (ipv6 < 0) 2017 goto parse_failed; 2018 else if (ipversion_set && np->ipv6 != (bool)ipv6) 2019 goto parse_failed; 2020 else 2021 np->ipv6 = (bool)ipv6; 2022 cur = delim + 1; 2023 2024 if (*cur != 0) { 2025 /* MAC address */ 2026 if (!mac_pton(cur, np->remote_mac)) 2027 goto parse_failed; 2028 } 2029 2030 netconsole_print_banner(np); 2031 2032 return 0; 2033 2034 parse_failed: 2035 np_info(np, "couldn't parse config at '%s'!\n", cur); 2036 return -1; 2037 } 2038 2039 /* Allocate new target (from boot/module param) and setup netpoll for it */ 2040 static struct netconsole_target *alloc_param_target(char *target_config, 2041 int cmdline_count) 2042 { 2043 struct netconsole_target *nt; 2044 int err; 2045 2046 nt = alloc_and_init(); 2047 if (!nt) { 2048 err = -ENOMEM; 2049 goto fail; 2050 } 2051 2052 if (*target_config == '+') { 2053 nt->extended = true; 2054 target_config++; 2055 } 2056 2057 if (*target_config == 'r') { 2058 if (!nt->extended) { 2059 pr_err("Netconsole configuration error. Release feature requires extended log message"); 2060 err = -EINVAL; 2061 goto fail; 2062 } 2063 nt->release = true; 2064 target_config++; 2065 } 2066 2067 /* Parse parameters and setup netpoll */ 2068 err = netconsole_parser_cmdline(&nt->np, target_config); 2069 if (err) 2070 goto fail; 2071 2072 err = netpoll_setup(&nt->np); 2073 if (err) { 2074 pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n", 2075 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count); 2076 if (!IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) 2077 /* only fail if dynamic reconfiguration is set, 2078 * otherwise, keep the target in the list, but disabled. 2079 */ 2080 goto fail; 2081 } else { 2082 nt->state = STATE_ENABLED; 2083 } 2084 populate_configfs_item(nt, cmdline_count); 2085 2086 return nt; 2087 2088 fail: 2089 kfree(nt); 2090 return ERR_PTR(err); 2091 } 2092 2093 /* Cleanup netpoll for given target (from boot/module param) and free it */ 2094 static void free_param_target(struct netconsole_target *nt) 2095 { 2096 cancel_work_sync(&nt->resume_wq); 2097 netpoll_cleanup(&nt->np); 2098 #ifdef CONFIG_NETCONSOLE_DYNAMIC 2099 kfree(nt->userdata); 2100 #endif 2101 kfree(nt); 2102 } 2103 2104 static struct console netconsole_ext = { 2105 .name = "netcon_ext", 2106 .flags = CON_ENABLED | CON_EXTENDED | CON_NBCON | CON_NBCON_ATOMIC_UNSAFE, 2107 .write_thread = netconsole_write_ext, 2108 .write_atomic = netconsole_write_ext, 2109 .device_lock = netconsole_device_lock, 2110 .device_unlock = netconsole_device_unlock, 2111 }; 2112 2113 static struct console netconsole = { 2114 .name = "netcon", 2115 .flags = CON_ENABLED | CON_NBCON | CON_NBCON_ATOMIC_UNSAFE, 2116 .write_thread = netconsole_write_basic, 2117 .write_atomic = netconsole_write_basic, 2118 .device_lock = netconsole_device_lock, 2119 .device_unlock = netconsole_device_unlock, 2120 }; 2121 2122 static int __init init_netconsole(void) 2123 { 2124 int err; 2125 struct netconsole_target *nt, *tmp; 2126 u32 console_type_needed = 0; 2127 unsigned int count = 0; 2128 unsigned long flags; 2129 char *target_config; 2130 char *input = config; 2131 2132 if (strnlen(input, MAX_PARAM_LENGTH)) { 2133 while ((target_config = strsep(&input, ";"))) { 2134 nt = alloc_param_target(target_config, count); 2135 if (IS_ERR(nt)) { 2136 if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) 2137 continue; 2138 err = PTR_ERR(nt); 2139 goto fail; 2140 } 2141 /* Dump existing printks when we register */ 2142 if (nt->extended) { 2143 console_type_needed |= CONS_EXTENDED; 2144 netconsole_ext.flags |= CON_PRINTBUFFER; 2145 } else { 2146 console_type_needed |= CONS_BASIC; 2147 netconsole.flags |= CON_PRINTBUFFER; 2148 } 2149 2150 spin_lock_irqsave(&target_list_lock, flags); 2151 list_add(&nt->list, &target_list); 2152 spin_unlock_irqrestore(&target_list_lock, flags); 2153 count++; 2154 } 2155 } 2156 2157 netconsole_wq = alloc_workqueue("netconsole", WQ_UNBOUND, 0); 2158 if (!netconsole_wq) { 2159 err = -ENOMEM; 2160 goto fail; 2161 } 2162 2163 err = register_netdevice_notifier(&netconsole_netdev_notifier); 2164 if (err) 2165 goto fail; 2166 2167 err = dynamic_netconsole_init(); 2168 if (err) 2169 goto undonotifier; 2170 2171 if (console_type_needed & CONS_EXTENDED) 2172 register_console(&netconsole_ext); 2173 if (console_type_needed & CONS_BASIC) 2174 register_console(&netconsole); 2175 pr_info("network logging started\n"); 2176 2177 return err; 2178 2179 undonotifier: 2180 unregister_netdevice_notifier(&netconsole_netdev_notifier); 2181 2182 fail: 2183 pr_err("cleaning up\n"); 2184 2185 if (netconsole_wq) 2186 flush_workqueue(netconsole_wq); 2187 /* 2188 * Remove all targets and destroy them (only targets created 2189 * from the boot/module option exist here). Skipping the list 2190 * lock is safe here, and netpoll_cleanup() will sleep. 2191 */ 2192 list_for_each_entry_safe(nt, tmp, &target_list, list) { 2193 list_del(&nt->list); 2194 free_param_target(nt); 2195 } 2196 2197 if (netconsole_wq) 2198 destroy_workqueue(netconsole_wq); 2199 2200 return err; 2201 } 2202 2203 static void __exit cleanup_netconsole(void) 2204 { 2205 struct netconsole_target *nt, *tmp; 2206 2207 if (console_is_registered(&netconsole_ext)) 2208 unregister_console(&netconsole_ext); 2209 if (console_is_registered(&netconsole)) 2210 unregister_console(&netconsole); 2211 dynamic_netconsole_exit(); 2212 unregister_netdevice_notifier(&netconsole_netdev_notifier); 2213 flush_workqueue(netconsole_wq); 2214 2215 /* 2216 * Targets created via configfs pin references on our module 2217 * and would first be rmdir(2)'ed from userspace. We reach 2218 * here only when they are already destroyed, and only those 2219 * created from the boot/module option are left, so remove and 2220 * destroy them. Skipping the list lock is safe here, and 2221 * netpoll_cleanup() will sleep. 2222 */ 2223 list_for_each_entry_safe(nt, tmp, &target_list, list) { 2224 list_del(&nt->list); 2225 free_param_target(nt); 2226 } 2227 2228 destroy_workqueue(netconsole_wq); 2229 } 2230 2231 /* 2232 * Use late_initcall to ensure netconsole is 2233 * initialized after network device driver if built-in. 2234 * 2235 * late_initcall() and module_init() are identical if built as module. 2236 */ 2237 late_initcall(init_netconsole); 2238 module_exit(cleanup_netconsole); 2239