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(sizeof(*nt), GFP_KERNEL); 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(sizeof(*udm), GFP_KERNEL); 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, msg); 1683 msg_len += release_len; 1684 } else { 1685 memcpy(nt->buf, msg, msg_len); 1686 } 1687 1688 if (userdata) 1689 msg_len += scnprintf(&nt->buf[msg_len], 1690 MAX_PRINT_CHUNK - msg_len, "%s", 1691 userdata); 1692 1693 if (sysdata) 1694 msg_len += scnprintf(&nt->buf[msg_len], 1695 MAX_PRINT_CHUNK - msg_len, "%s", 1696 sysdata); 1697 1698 send_udp(nt, nt->buf, msg_len); 1699 } 1700 1701 static void append_release(char *buf) 1702 { 1703 const char *release; 1704 1705 release = init_utsname()->release; 1706 scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release); 1707 } 1708 1709 static void send_fragmented_body(struct netconsole_target *nt, 1710 const char *msgbody_ptr, int header_len, 1711 int msgbody_len, int sysdata_len) 1712 { 1713 const char *userdata_ptr = NULL; 1714 const char *sysdata_ptr = NULL; 1715 int data_len, data_sent = 0; 1716 int userdata_offset = 0; 1717 int sysdata_offset = 0; 1718 int msgbody_offset = 0; 1719 int userdata_len = 0; 1720 1721 #ifdef CONFIG_NETCONSOLE_DYNAMIC 1722 userdata_ptr = nt->userdata; 1723 sysdata_ptr = nt->sysdata; 1724 userdata_len = nt->userdata_length; 1725 #endif 1726 if (WARN_ON_ONCE(!userdata_ptr && userdata_len != 0)) 1727 return; 1728 1729 if (WARN_ON_ONCE(!sysdata_ptr && sysdata_len != 0)) 1730 return; 1731 1732 /* data_len represents the number of bytes that will be sent. This is 1733 * bigger than MAX_PRINT_CHUNK, thus, it will be split in multiple 1734 * packets 1735 */ 1736 data_len = msgbody_len + userdata_len + sysdata_len; 1737 1738 /* In each iteration of the while loop below, we send a packet 1739 * containing the header and a portion of the data. The data is 1740 * composed of three parts: msgbody, userdata, and sysdata. 1741 * We keep track of how many bytes have been sent from each part using 1742 * the *_offset variables. 1743 * We keep track of how many bytes have been sent overall using the 1744 * data_sent variable, which ranges from 0 to the total bytes to be 1745 * sent. 1746 */ 1747 while (data_sent < data_len) { 1748 int userdata_left = userdata_len - userdata_offset; 1749 int sysdata_left = sysdata_len - sysdata_offset; 1750 int msgbody_left = msgbody_len - msgbody_offset; 1751 int buf_offset = 0; 1752 int this_chunk = 0; 1753 1754 /* header is already populated in nt->buf, just append to it */ 1755 buf_offset = header_len; 1756 1757 buf_offset += scnprintf(nt->buf + buf_offset, 1758 MAX_PRINT_CHUNK - buf_offset, 1759 ",ncfrag=%d/%d;", data_sent, 1760 data_len); 1761 1762 /* append msgbody first */ 1763 this_chunk = min(msgbody_left, MAX_PRINT_CHUNK - buf_offset); 1764 memcpy(nt->buf + buf_offset, msgbody_ptr + msgbody_offset, 1765 this_chunk); 1766 msgbody_offset += this_chunk; 1767 buf_offset += this_chunk; 1768 data_sent += this_chunk; 1769 1770 /* after msgbody, append userdata */ 1771 if (userdata_ptr && userdata_left) { 1772 this_chunk = min(userdata_left, 1773 MAX_PRINT_CHUNK - buf_offset); 1774 memcpy(nt->buf + buf_offset, 1775 userdata_ptr + userdata_offset, this_chunk); 1776 userdata_offset += this_chunk; 1777 buf_offset += this_chunk; 1778 data_sent += this_chunk; 1779 } 1780 1781 /* after userdata, append sysdata */ 1782 if (sysdata_ptr && sysdata_left) { 1783 this_chunk = min(sysdata_left, 1784 MAX_PRINT_CHUNK - buf_offset); 1785 memcpy(nt->buf + buf_offset, 1786 sysdata_ptr + sysdata_offset, this_chunk); 1787 sysdata_offset += this_chunk; 1788 buf_offset += this_chunk; 1789 data_sent += this_chunk; 1790 } 1791 1792 /* if all is good, send the packet out */ 1793 if (WARN_ON_ONCE(data_sent > data_len)) 1794 return; 1795 1796 send_udp(nt, nt->buf, buf_offset); 1797 } 1798 } 1799 1800 static void send_msg_fragmented(struct netconsole_target *nt, 1801 const char *msg, 1802 int msg_len, 1803 int release_len, 1804 int sysdata_len) 1805 { 1806 int header_len, msgbody_len; 1807 const char *msgbody; 1808 1809 /* need to insert extra header fields, detect header and msgbody */ 1810 msgbody = memchr(msg, ';', msg_len); 1811 if (WARN_ON_ONCE(!msgbody)) 1812 return; 1813 1814 header_len = msgbody - msg; 1815 msgbody_len = msg_len - header_len - 1; 1816 msgbody++; 1817 1818 /* 1819 * Transfer multiple chunks with the following extra header. 1820 * "ncfrag=<byte-offset>/<total-bytes>" 1821 */ 1822 if (release_len) 1823 append_release(nt->buf); 1824 1825 /* Copy the header into the buffer */ 1826 memcpy(nt->buf + release_len, msg, header_len); 1827 header_len += release_len; 1828 1829 /* for now on, the header will be persisted, and the msgbody 1830 * will be replaced 1831 */ 1832 send_fragmented_body(nt, msgbody, header_len, msgbody_len, 1833 sysdata_len); 1834 } 1835 1836 /** 1837 * send_ext_msg_udp - send extended log message to target 1838 * @nt: target to send message to 1839 * @wctxt: nbcon write context containing message and metadata 1840 * 1841 * Transfer extended log message to @nt. If message is longer than 1842 * MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with 1843 * ncfrag header field added to identify them. 1844 */ 1845 static void send_ext_msg_udp(struct netconsole_target *nt, 1846 struct nbcon_write_context *wctxt) 1847 { 1848 int userdata_len = 0; 1849 int release_len = 0; 1850 int sysdata_len = 0; 1851 int len; 1852 1853 #ifdef CONFIG_NETCONSOLE_DYNAMIC 1854 sysdata_len = prepare_sysdata(nt, wctxt); 1855 userdata_len = nt->userdata_length; 1856 #endif 1857 if (nt->release) 1858 release_len = strlen(init_utsname()->release) + 1; 1859 1860 len = wctxt->len + release_len + sysdata_len + userdata_len; 1861 if (len <= MAX_PRINT_CHUNK) 1862 return send_msg_no_fragmentation(nt, wctxt->outbuf, 1863 wctxt->len, release_len); 1864 1865 return send_msg_fragmented(nt, wctxt->outbuf, wctxt->len, release_len, 1866 sysdata_len); 1867 } 1868 1869 static void send_msg_udp(struct netconsole_target *nt, const char *msg, 1870 unsigned int len) 1871 { 1872 const char *tmp = msg; 1873 int frag, left = len; 1874 1875 while (left > 0) { 1876 frag = min(left, MAX_PRINT_CHUNK); 1877 send_udp(nt, tmp, frag); 1878 tmp += frag; 1879 left -= frag; 1880 } 1881 } 1882 1883 /** 1884 * netconsole_write - Generic function to send a msg to all targets 1885 * @wctxt: nbcon write context 1886 * @extended: "true" for extended console mode 1887 * 1888 * Given an nbcon write context, send the message to the netconsole targets 1889 */ 1890 static void netconsole_write(struct nbcon_write_context *wctxt, bool extended) 1891 { 1892 struct netconsole_target *nt; 1893 1894 if (oops_only && !oops_in_progress) 1895 return; 1896 1897 list_for_each_entry(nt, &target_list, list) { 1898 if (nt->extended != extended || nt->state != STATE_ENABLED || 1899 !netif_running(nt->np.dev)) 1900 continue; 1901 1902 /* If nbcon_enter_unsafe() fails, just return given netconsole 1903 * lost the ownership, and iterating over the targets will not 1904 * be able to re-acquire. 1905 */ 1906 if (!nbcon_enter_unsafe(wctxt)) 1907 return; 1908 1909 if (extended) 1910 send_ext_msg_udp(nt, wctxt); 1911 else 1912 send_msg_udp(nt, wctxt->outbuf, wctxt->len); 1913 1914 nbcon_exit_unsafe(wctxt); 1915 } 1916 } 1917 1918 static void netconsole_write_ext(struct console *con __always_unused, 1919 struct nbcon_write_context *wctxt) 1920 { 1921 netconsole_write(wctxt, true); 1922 } 1923 1924 static void netconsole_write_basic(struct console *con __always_unused, 1925 struct nbcon_write_context *wctxt) 1926 { 1927 netconsole_write(wctxt, false); 1928 } 1929 1930 static void netconsole_device_lock(struct console *con __always_unused, 1931 unsigned long *flags) 1932 __acquires(&target_list_lock) 1933 { 1934 spin_lock_irqsave(&target_list_lock, *flags); 1935 } 1936 1937 static void netconsole_device_unlock(struct console *con __always_unused, 1938 unsigned long flags) 1939 __releases(&target_list_lock) 1940 { 1941 spin_unlock_irqrestore(&target_list_lock, flags); 1942 } 1943 1944 static int netconsole_parser_cmdline(struct netpoll *np, char *opt) 1945 { 1946 bool ipversion_set = false; 1947 char *cur = opt; 1948 char *delim; 1949 int ipv6; 1950 1951 if (*cur != '@') { 1952 delim = strchr(cur, '@'); 1953 if (!delim) 1954 goto parse_failed; 1955 *delim = 0; 1956 if (kstrtou16(cur, 10, &np->local_port)) 1957 goto parse_failed; 1958 cur = delim; 1959 } 1960 cur++; 1961 1962 if (*cur != '/') { 1963 ipversion_set = true; 1964 delim = strchr(cur, '/'); 1965 if (!delim) 1966 goto parse_failed; 1967 *delim = 0; 1968 ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip); 1969 if (ipv6 < 0) 1970 goto parse_failed; 1971 else 1972 np->ipv6 = (bool)ipv6; 1973 cur = delim; 1974 } 1975 cur++; 1976 1977 if (*cur != ',') { 1978 /* parse out dev_name or dev_mac */ 1979 delim = strchr(cur, ','); 1980 if (!delim) 1981 goto parse_failed; 1982 *delim = 0; 1983 1984 np->dev_name[0] = '\0'; 1985 eth_broadcast_addr(np->dev_mac); 1986 if (!strchr(cur, ':')) 1987 strscpy(np->dev_name, cur, sizeof(np->dev_name)); 1988 else if (!mac_pton(cur, np->dev_mac)) 1989 goto parse_failed; 1990 1991 cur = delim; 1992 } 1993 cur++; 1994 1995 if (*cur != '@') { 1996 /* dst port */ 1997 delim = strchr(cur, '@'); 1998 if (!delim) 1999 goto parse_failed; 2000 *delim = 0; 2001 if (*cur == ' ' || *cur == '\t') 2002 np_info(np, "warning: whitespace is not allowed\n"); 2003 if (kstrtou16(cur, 10, &np->remote_port)) 2004 goto parse_failed; 2005 cur = delim; 2006 } 2007 cur++; 2008 2009 /* dst ip */ 2010 delim = strchr(cur, '/'); 2011 if (!delim) 2012 goto parse_failed; 2013 *delim = 0; 2014 ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip); 2015 if (ipv6 < 0) 2016 goto parse_failed; 2017 else if (ipversion_set && np->ipv6 != (bool)ipv6) 2018 goto parse_failed; 2019 else 2020 np->ipv6 = (bool)ipv6; 2021 cur = delim + 1; 2022 2023 if (*cur != 0) { 2024 /* MAC address */ 2025 if (!mac_pton(cur, np->remote_mac)) 2026 goto parse_failed; 2027 } 2028 2029 netconsole_print_banner(np); 2030 2031 return 0; 2032 2033 parse_failed: 2034 np_info(np, "couldn't parse config at '%s'!\n", cur); 2035 return -1; 2036 } 2037 2038 /* Allocate new target (from boot/module param) and setup netpoll for it */ 2039 static struct netconsole_target *alloc_param_target(char *target_config, 2040 int cmdline_count) 2041 { 2042 struct netconsole_target *nt; 2043 int err; 2044 2045 nt = alloc_and_init(); 2046 if (!nt) { 2047 err = -ENOMEM; 2048 goto fail; 2049 } 2050 2051 if (*target_config == '+') { 2052 nt->extended = true; 2053 target_config++; 2054 } 2055 2056 if (*target_config == 'r') { 2057 if (!nt->extended) { 2058 pr_err("Netconsole configuration error. Release feature requires extended log message"); 2059 err = -EINVAL; 2060 goto fail; 2061 } 2062 nt->release = true; 2063 target_config++; 2064 } 2065 2066 /* Parse parameters and setup netpoll */ 2067 err = netconsole_parser_cmdline(&nt->np, target_config); 2068 if (err) 2069 goto fail; 2070 2071 err = netpoll_setup(&nt->np); 2072 if (err) { 2073 pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n", 2074 NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count); 2075 if (!IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) 2076 /* only fail if dynamic reconfiguration is set, 2077 * otherwise, keep the target in the list, but disabled. 2078 */ 2079 goto fail; 2080 } else { 2081 nt->state = STATE_ENABLED; 2082 } 2083 populate_configfs_item(nt, cmdline_count); 2084 2085 return nt; 2086 2087 fail: 2088 kfree(nt); 2089 return ERR_PTR(err); 2090 } 2091 2092 /* Cleanup netpoll for given target (from boot/module param) and free it */ 2093 static void free_param_target(struct netconsole_target *nt) 2094 { 2095 cancel_work_sync(&nt->resume_wq); 2096 netpoll_cleanup(&nt->np); 2097 #ifdef CONFIG_NETCONSOLE_DYNAMIC 2098 kfree(nt->userdata); 2099 #endif 2100 kfree(nt); 2101 } 2102 2103 static struct console netconsole_ext = { 2104 .name = "netcon_ext", 2105 .flags = CON_ENABLED | CON_EXTENDED | CON_NBCON | CON_NBCON_ATOMIC_UNSAFE, 2106 .write_thread = netconsole_write_ext, 2107 .write_atomic = netconsole_write_ext, 2108 .device_lock = netconsole_device_lock, 2109 .device_unlock = netconsole_device_unlock, 2110 }; 2111 2112 static struct console netconsole = { 2113 .name = "netcon", 2114 .flags = CON_ENABLED | CON_NBCON | CON_NBCON_ATOMIC_UNSAFE, 2115 .write_thread = netconsole_write_basic, 2116 .write_atomic = netconsole_write_basic, 2117 .device_lock = netconsole_device_lock, 2118 .device_unlock = netconsole_device_unlock, 2119 }; 2120 2121 static int __init init_netconsole(void) 2122 { 2123 int err; 2124 struct netconsole_target *nt, *tmp; 2125 u32 console_type_needed = 0; 2126 unsigned int count = 0; 2127 unsigned long flags; 2128 char *target_config; 2129 char *input = config; 2130 2131 if (strnlen(input, MAX_PARAM_LENGTH)) { 2132 while ((target_config = strsep(&input, ";"))) { 2133 nt = alloc_param_target(target_config, count); 2134 if (IS_ERR(nt)) { 2135 if (IS_ENABLED(CONFIG_NETCONSOLE_DYNAMIC)) 2136 continue; 2137 err = PTR_ERR(nt); 2138 goto fail; 2139 } 2140 /* Dump existing printks when we register */ 2141 if (nt->extended) { 2142 console_type_needed |= CONS_EXTENDED; 2143 netconsole_ext.flags |= CON_PRINTBUFFER; 2144 } else { 2145 console_type_needed |= CONS_BASIC; 2146 netconsole.flags |= CON_PRINTBUFFER; 2147 } 2148 2149 spin_lock_irqsave(&target_list_lock, flags); 2150 list_add(&nt->list, &target_list); 2151 spin_unlock_irqrestore(&target_list_lock, flags); 2152 count++; 2153 } 2154 } 2155 2156 netconsole_wq = alloc_workqueue("netconsole", WQ_UNBOUND, 0); 2157 if (!netconsole_wq) { 2158 err = -ENOMEM; 2159 goto fail; 2160 } 2161 2162 err = register_netdevice_notifier(&netconsole_netdev_notifier); 2163 if (err) 2164 goto fail; 2165 2166 err = dynamic_netconsole_init(); 2167 if (err) 2168 goto undonotifier; 2169 2170 if (console_type_needed & CONS_EXTENDED) 2171 register_console(&netconsole_ext); 2172 if (console_type_needed & CONS_BASIC) 2173 register_console(&netconsole); 2174 pr_info("network logging started\n"); 2175 2176 return err; 2177 2178 undonotifier: 2179 unregister_netdevice_notifier(&netconsole_netdev_notifier); 2180 2181 fail: 2182 pr_err("cleaning up\n"); 2183 2184 if (netconsole_wq) 2185 flush_workqueue(netconsole_wq); 2186 /* 2187 * Remove all targets and destroy them (only targets created 2188 * from the boot/module option exist here). Skipping the list 2189 * lock is safe here, and netpoll_cleanup() will sleep. 2190 */ 2191 list_for_each_entry_safe(nt, tmp, &target_list, list) { 2192 list_del(&nt->list); 2193 free_param_target(nt); 2194 } 2195 2196 if (netconsole_wq) 2197 destroy_workqueue(netconsole_wq); 2198 2199 return err; 2200 } 2201 2202 static void __exit cleanup_netconsole(void) 2203 { 2204 struct netconsole_target *nt, *tmp; 2205 2206 if (console_is_registered(&netconsole_ext)) 2207 unregister_console(&netconsole_ext); 2208 if (console_is_registered(&netconsole)) 2209 unregister_console(&netconsole); 2210 dynamic_netconsole_exit(); 2211 unregister_netdevice_notifier(&netconsole_netdev_notifier); 2212 flush_workqueue(netconsole_wq); 2213 2214 /* 2215 * Targets created via configfs pin references on our module 2216 * and would first be rmdir(2)'ed from userspace. We reach 2217 * here only when they are already destroyed, and only those 2218 * created from the boot/module option are left, so remove and 2219 * destroy them. Skipping the list lock is safe here, and 2220 * netpoll_cleanup() will sleep. 2221 */ 2222 list_for_each_entry_safe(nt, tmp, &target_list, list) { 2223 list_del(&nt->list); 2224 free_param_target(nt); 2225 } 2226 2227 destroy_workqueue(netconsole_wq); 2228 } 2229 2230 /* 2231 * Use late_initcall to ensure netconsole is 2232 * initialized after network device driver if built-in. 2233 * 2234 * late_initcall() and module_init() are identical if built as module. 2235 */ 2236 late_initcall(init_netconsole); 2237 module_exit(cleanup_netconsole); 2238