[PATCH] netconsole: avoid null pointer dereference at show_local_mac()
From: Keiichi KII <[EMAIL PROTECTED]> This patch avoids a null pointer dereference when we read local_mac for netconsole in configfs and shows default local mac address value. A null pointer dereference occurs when we call show_local_mac() via local_mac entry in configfs before we setup the content of netpoll using netpoll_setup(). This patch is for 2.6.25-rc1. Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- Index: pre-release/drivers/net/netconsole.c === --- pre-release.orig/drivers/net/netconsole.c +++ pre-release/drivers/net/netconsole.c @@ -309,8 +309,8 @@ static ssize_t show_local_mac(struct net struct net_device *dev = nt->np.dev; DECLARE_MAC_BUF(mac); - return snprintf(buf, PAGE_SIZE, "%s\n", - print_mac(mac, dev->dev_addr)); + return snprintf(buf, PAGE_SIZE, "%s\n", dev ? + print_mac(mac, dev->dev_addr) : "ff:ff:ff:ff:ff:ff"); } static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] fix typo in SubmittingPatches
From: Keiichi Kii <[EMAIL PROTECTED]> Greg, could you replace old patch with new one? Fix typo and insert " -- " between clauses. Signed-off-by: Keiichi Kii <[EMAIL PROTECTED]> Cc: Andy Whitcroft <[EMAIL PROTECTED]> --- Index: trunk/Documentation/SubmittingPatches === --- trunk.orig/Documentation/SubmittingPatches +++ trunk/Documentation/SubmittingPatches @@ -464,8 +464,8 @@ section Linus Computer Science 101. Nuff said. If your code deviates too much from this, it is likely to be rejected without further review, and without comment. -Once significant exception is when moving code from one file to -another in this case you should not modify the moved code at all in +One significant exception is when moving code from one file to +another -- in this case you should not modify the moved code at all in the same patch which moves it. This clearly delineates the act of moving the code and your changes. This greatly aids review of the actual differences and allows tools to better track the history of -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] fix typo in SubmittingPatches
Hi, -Once significant exception is when moving code from one file to +One significant exception is when moving code from one file to another in this case you should not modify the moved code at all in the same patch which moves it. This clearly delineates the act of moving the code and your changes. This greatly aids review of the That first sentence is still broken. It should be more like this, with either a ":" or ";" or " -- " between clauses: One significant exception is when moving code from one file to another -- in this case you should not modify the moved code at all in the same patch which moves it. Tahnks for your point. I will fix this sentence as above. -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] add SubmittingPatches to Documentation/ja_JP
Thank you for your reply! Basically okay, but please refer to the original DCO document. What is "DCO document"? DCO stands for Developer's Certificate of Origin in SumittingPatches? If so, I will put original text of the DCO into the translated SubmittingPatches. If not so, please tell me about DCO document. Your mailer is broken. You should include "charset" parameter in your multipart. Maybe it is better to prepare a git repository, or attach it as a binary (application/octet-stream). Thanks, I couldn't notice possibility of false recognition of character code because there was no probelm in my environment. But, I used mew as MUA and the patch was recognized as Ascii, not UTF-8. I think alternative based on your suggestions. Thanks --yoshfuji In article <[EMAIL PROTECTED]> (at Fri, 26 Oct 2007 15:55:24 +0900), Keiichi KII <[EMAIL PROTECTED]> says: From: Keiichi Kii <[EMAIL PROTECTED]> This patch adds SubmittingPatches translated into Japanese to Documentation/ja_JP directory. I attach the patch because there is a possibility that MUA will change the character encoding sometimes. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] add SubmittingPatches to Documentation/ja_JP
From: Keiichi Kii <[EMAIL PROTECTED]> This patch adds SubmittingPatches translated into Japanese to Documentation/ja_JP directory. I attach the patch because there is a possibility that MUA will change the character encoding sometimes. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] Index: trunk/Documentation/ja_JP/SubmittingPatches === --- /dev/null +++ trunk/Documentation/ja_JP/SubmittingPatches @@ -0,0 +1,556 @@ +NOTE: +This is a version of Documentation/SubmittingPatches into Japanese. +This document is maintained by Keiichi KII <[EMAIL PROTECTED]> +and the JF Project team <http://www.linux.or.jp/JF/>. +If you find any difference between this document and the original file +or a problem with the translation, +please contact the maintainer of this file or JF project. + +Please also note that the purpose of this file is to be easier to read +for non English (read: Japanese) speakers and is not intended as a +fork. So if you have any comments or updates of this file, please try +to update the original English file first. + +Last Updated: 2007/10/24 +== +ããã¯ã +linux-2.6.23/Documentation/SubmittingPatches ã®å訳 +ã§ãã +翻訳å£ä½ï¼ JF ããã¸ã§ã¯ã < http://www.linux.or.jp/JF/ > +翻訳æ¥ï¼ 2007/10/17 +翻訳è ï¼ Keiichi Kii +æ ¡æ£è ï¼ Masanari Kobayashi ãã + Matsukura ãã +== + +Linux ã«ã¼ãã«ã«å¤æ´ãå ããããã® Howto +å㯠+ãã® Linus Torvalds ã®åãæ±ã説ææ¸ + +Linux ã«ã¼ãã«ã«å¤æ´ãå ãããã¨æã£ã¦ããå人åã¯ä¼ç¤¾ã«ã¨ã£ã¦ããã +ãã®æ稿ã«é¢é£ããä»çµã¿ã«æ £ãã¦ããªããã°ããã®éç¨ã¯æã ã¿ãªããã +ãããã¥ããããã¨ãããã¾ãããã®æç« ã¯ããªãã®å¤æ´ã大ãã«åãå ¥ã +ã¦ããããããããææ¡ãéãããã®ã§ãã + +ã³ã¼ããæ稿ããåã«ãDocumentation/SubmitChecklist ã®é ç®ãªã¹ãã«ç® +ãéãã¦ãã§ãã¯ãã¦ãã ãããããããªãããã©ã¤ãã¼ãæ稿ãããã¨ã +ã¦ãããªããDocumentation/SubmittingDrivers ã«ãç®ãéãã¦ãã ããã + + +ã»ã¯ã·ã§ã³1 ãããã®ä½ãæ¹ã¨éãæ¹ + + +1) ã diff -up ã + + +ãããã®ä½æã«ã¯ã diff -up ãåã¯ã diff -uprN ãã使ã£ã¦ãã ããã + +Linux ã«ã¼ãã«ã«å¯¾ããå ¨ã¦ã®å¤æ´ã¯ diff(1) ã³ãã³ãã«ãããããã®å½¢å¼ã§ +çæãã¦ãã ãããããããä½æããã¨ãã«ã¯ãdiff(1) ã³ãã³ãã«ã -u ãå¼ +æ°ãæå®ãã¦ãunified å½¢å¼ã®ããããä½æãããã¨ã確èªãã¦ãã ãããã¾ãã +å¤æ´ãã©ã® C é¢æ°ã§è¡ãããã®ãã表示ããã -p ãå¼æ°ã使ã£ã¦ãã ããã +ãã®å¼æ°ã¯çæããå·®åããã£ã¨èªã¿ããããã¦ããã¾ããããã㯠Linux +ã«ã¼ãã«ã½ã¼ã¹ã®ä¸ã®ãµããã£ã¬ã¯ããªã§ã¯ãªã Linux ã«ã¼ãã«ã½ã¼ã¹ã®ã«ã¼ã +ãã£ã¬ã¯ããªãåºæºã«ããªãã¨ããã¾ããã + +1åã®ãã¡ã¤ã«ã«ã¤ãã¦ã®ããããä½æããããã«ã¯ãã»ã¨ãã©ã®å ´åã +以ä¸ã®ä½æ¥ãè¡ãã°ååã§ãã + + SRCTREE= linux-2.6 + MYFILE= drivers/net/mydriver.c + + cd $SRCTREE + cp $MYFILE $MYFILE.orig + vi $MYFILE # make your change + cd .. + diff -up $SRCTREE/$MYFILE{.orig,} > /tmp/patch + +è¤æ°ã®ãã¡ã¤ã«ã«ã¤ãã¦ã®ããããä½æããããã«ã¯ãç´ ã®( vanilla )ãã +ãªãã¡å¤æ´ãå ãã¦ãªã Linux ã«ã¼ãã«ãå±éããèªåã® Linux ã«ã¼ãã« +ã½ã¼ã¹ã¨ã®å·®åãçæããªãã¨ããã¾ãããä¾ãã°ã + + MYSRC= /devel/linux-2.6 + + tar xvfz linux-2.6.12.tar.gz + mv linux-2.6.12 linux-2.6.12-vanilla + diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \ + linux-2.6.12-vanilla $MYSRC > /tmp/patch + +dontdiff ãã¡ã¤ã«ã«ã¯ Linux ã«ã¼ãã«ã®ãã«ãããã»ã¹ã®éç¨ã§çæããã +ãã¡ã¤ã«ã®ä¸è¦§ãã®ã£ã¦ãã¾ããããã¦ããããã¯ããããçæãã diff(1) +ã³ãã³ãã§ç¡è¦ãããã¹ãã§ããdontdiff ãã¡ã¤ã«ã¯ 2.6.12 以å¾ã®ãã¼ã¸ã§ +ã³ã® Linux ã«ã¼ãã«ã½ã¼ã¹ããªã¼ã«å«ã¾ãã¦ãã¾ããããããåã®ãã¼ã¸ã§ã³ +ã® Linux ã«ã¼ãã«ã½ã¼ã¹ããªã¼ã«å¯¾ãã dontdiff ãã¡ã¤ã«ã¯ã +<http://www.xenotime.net/linux/doc/dontdiff>ããåå¾ãããã¨ãã§ãã¾ãã + +æ稿ãããããã®ä¸ã«é¢ä¿ã®ãªãä½åãªãã¡ã¤ã«ãå«ã¾ãã¦ããªãã
[PATCH 1/2] fix typo in SubmittingPatches
From: Keiichi Kii <[EMAIL PROTECTED]> Fix typo. Signed-off-by: Keiichi Kii <[EMAIL PROTECTED]> Cc: Andy Whitcroft <[EMAIL PROTECTED]> --- Index: trunk/Documentation/SubmittingPatches === --- trunk.orig/Documentation/SubmittingPatches +++ trunk/Documentation/SubmittingPatches @@ -464,7 +464,7 @@ section Linus Computer Science 101. Nuff said. If your code deviates too much from this, it is likely to be rejected without further review, and without comment. -Once significant exception is when moving code from one file to +One significant exception is when moving code from one file to another in this case you should not modify the moved code at all in the same patch which moves it. This clearly delineates the act of moving the code and your changes. This greatly aids review of the -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/2] Japanese translation of Documentation/SubmittingPatches
From: Keiichi Kii <[EMAIL PROTECTED]> Hi all, Currently, HOWTO and stable_api_nonsense.txt are included in Documentation/"each country"/ as policy documents. Greg K-H said the following in this thread: (http://www.uwsg.iu.edu/hypermail/linux/kernel/0706.1/0897.html) > So I really do want to see a translated copy of the HOWTO, > stable-api-nonsense.txt, and possibly a few other files in the main > kernel tree (SubmittingPatches, CodingStyle, and SubmittingDrivers might > all be good canidates for this.) These files change relativly > infrequently (the HOWTO file has had only 7 changes in 1 and 1/2 years, > and they were very minor ones) and should be easy for the translators to > keep up with. SubmittingPatches document includes important information about how to generate patch and write e-mail related to kernel development. So, I wish SubmittingPatches is included in Documentation/"each country"/ as policy documents. How do you think about this? I attach two patches(one fixes a typo, the other adds SubmittingPatches translated into Japanese to Documentation/ja_JP directory). These patches are for linux-2.6.23. The translated SubmittingPatches has already been reviewed by JF project. JF project is the Japanese equivalent of LDP. Your comments are very welcome. Signed-off-by: Keiichi Kii <[EMAIL PROTECTED]> -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v2 -mm 9/9] netconsole: Support dynamic reconfiguration using configfs
Hi Satyam, > struct netconsole_target { > struct list_headlist; > +#ifdef CONFIG_NETCONSOLE_DYNAMIC > + struct config_item item; > + int enabled; > +#endif > struct netpoll np; > }; If CONFIG_NETCONSOLE_DYNAMIC is unset, we can't access to the "enabled" member. So, the compile errors occur because the following functions make use of the above one. > +/* Allocate new target (from boot/module param) and setup netpoll for it */ > +static struct netconsole_target *alloc_param_target(char *target_config) > { > int err = -ENOMEM; > struct netconsole_target *nt; > > - /* Allocate and initialize with defaults */ > + /* > + * Allocate and initialize with defaults. > + * Note that these targets get their config_item fields zeroed-out. > + */ > nt = kzalloc(sizeof(*nt), GFP_KERNEL); > if (!nt) { > printk(KERN_ERR "netconsole: failed to allocate memory\n"); > @@ -106,6 +188,8 @@ static struct netconsole_target *alloc_t > if (err) > goto fail; > > + nt->enabled = 1; > + > return nt; > > fail: > @@ -113,13 +197,469 @@ fail: > return ERR_PTR(err); > } > @@ -169,7 +711,8 @@ static void write_msg(struct console *co > > spin_lock_irqsave(&target_list_lock, flags); > list_for_each_entry(nt, &target_list, list) { > - if (netif_running(nt->np.dev)) { > + netconsole_target_get(nt); > + if (nt->enabled && netif_running(nt->np.dev)) { > /* >* We nest this inside the for-each-target loop above >* so that we're able to get as much logging out to > @@ -184,6 +727,7 @@ static void write_msg(struct console *co > left -= frag; > } > } > + netconsole_target_put(nt); > } > spin_unlock_irqrestore(&target_list_lock, flags); > } I created the following patch for performing some tests. If there is nothing wrong with the patch, I'm going to continue to test. Signed-off-by: Keiichi Kii <[EMAIL PROTECTED]> Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -94,8 +94,8 @@ struct netconsole_target { struct list_head list; #ifdef CONFIG_NETCONSOLE_DYNAMIC struct config_item item; - int enabled; #endif + int enabled; struct netpoll np; }; Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH v2 -mm 0/9] netconsole: Multiple targets and dynamic reconfigurability
Hi Satyam, I'm going to test/review these patches and report the result of tests on IA64/x86 until this Friday. > [0/9] netconsole: Multiple targets and dynamic reconfigurability > > This patchset is a rework of the original idea and patches posted by > Keiichi Kii and Takayoshi Kochi at: http://lkml.org/lkml/2007/6/13/72 > > This is v2 of the patchset, the previous version is available at: > http://lkml.org/lkml/2007/7/4/107 > > This is diffed against 2.6.22-rc6-mm1 + the earlier netpoll fixlet and the > configfs cleanup patches (those are already merged in -mm AFAIK, and hence > not reproduced here). > > [1/9] netconsole: Cleanups, codingstyle, prettyfication > [2/9] netconsole: Remove bogus check > [3/9] netconsole: Simplify boot/module option setup logic > [4/9] netconsole: Add some useful tips to documentation > [5/9] netconsole: Introduce netconsole_target > [6/9] netconsole: Introduce netconsole_netdev_notifier > [7/9] netconsole: Use netif_running() in write_msg() > [8/9] netconsole: Support multiple logging targets > [9/9] netconsole: Support dynamic reconfiguration using configfs Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH -mm 8/9] netconsole: Update documentation for dynamic reconfigurability
Hi Satyam, > + cat enabled # check if enabled is 1 > + echo 0 > enabled# disable the target (if required) > + echo eth2 > dev_name# set local interface I think that the above line should change from "echo eth2 > dev_name" to "echo -n eth2 > dev_name" or the newline should be removed at store_dev_name(). The default behavior of echo(1) outputs the newline. So, if we write appropriate network device name to dev_name, the netpoll can't find net_device in netpoll_setup(). I don't have enough time now. So I will check your patches more specific at the weekend. Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm 0/9] netconsole: Multiple targets and dynamic reconfigurability
Hi Satyam, At first, thank you for your helping. I'm going to try/review your patches. >[ I had initially thought about only modifying Keiichi's patches to >incorporate the suggested stuff, sysfs+ioctl->configfs conversion, etc, >but the changes became too much and I ultimately ended up rewriting the >patchset. This also gave the flexibility to make other changes possible. >Keiichi, Takayoshi, kindly review this, and if OK, please give your >Signed-off-by:'s to the patches herein. ] By the way, how can I add Signed-off-by:'s to your patches? Should I add it to each patch and submit them to this list again? Anybody could give me an advice? -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take5 4/7] using symlink for the net_device
Hello Satyam, In any case, however, the point to extend the critical section here to encapsulate all the three parts still stands. We wouldn't want ioctl(NETCON_REMOVE_TARGET) on the specified target to return without removing the target that the user specified just because that target's ethernet interface happens to be currently undergoing a name change. The correct behaviour would be to sleep on a mutex till the renaming has completed (which will then relinquish the mutex) and then (after acquiring the mutex) proceed to remove it, IMHO. You're right. I misunderstood. All the three parts needs to encapsulate. >> +static char *make_netdev_class_name(char *netdev_name) >> +{ >> + char *name; >> + >> + name = kasprintf(GFP_KERNEL, "net:%s", netdev_name); > > Why the "net:" prefix in the filename? Because I drew upon dev_change_name() method in net/core/dev.c. The device_rename() in the above function makes use of same prefix related to netdev. I think you're referring to make_class_name() here? That seems to be somewhat bulkier than simply being a wrapper over kasprintf() like the make_netdev_class_name() here. I'd definitely recommend not obfuscating this simple functionality here. I understand. The wrapper method such as make_netdev_class_name() isn't appropriate in this case. Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take5 6/7] add ioctls for adding/removing target
Hello Satyam, Hmm, I might've missed this thread, but my opinion on the alternatives, fwiw: 1. I think adding new ioctl's to the kernel are generally disliked for obvious reasons. Perhaps Stephen meant to add some generic ioctl's above (and not separate ones specially implemented for the dynamically reconfigurable netconsole driver)? You're right. At first, I implemented ioctls to misc device because of using misc sysfs. But, Andrew Morton said "Using an ioctl() against a miscdev is rather untypical for networking.". So, I implemented ioclts to tty_driver. Please do consider configfs. Note that we'll have to lose the sysfs symlink from your target's kobject to the kobject of the ethernet device if we switch to configfs, but was that symlink needed for some essential functionality or was it simply for informational purpose? IMHO, this patchset only needs to bring in functionality to be able to create, destroy, and modify netconsole targets at run-time, and all these reconfiguration tasks would be handled quite well by configfs, AFAICT. It was for informational pupose. But, if we used symlink to the net_device kobject in sysfs, we could easily keep up with changing network device name by changing symbolic link. In the case of configfs, Do we use config_item related to the network interface because the configfs doesn't have symlink that refers to net_device kobject (e.g. "network_interface" in configfs, "network_interface" value is "eth0")? I'm going to search configfs and modify interface to configfs. Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take5 4/7] using symlink for the net_device
Hello Satyam, and this is why we have to use the dual-list mechanism to react to the net device rename. This isn't so obvious, a comment at the point where you declare modify_target_list would be nice? (BTW temporary_list would be a better name for that, IMO) All right, my patches are short of comments. So, I will add comments to the ambiguous codes. Ok, so reading through the code makes it obvious that this mutex is used to protect against the following race: Thread #1 Thread #2 = = [ NETDEV_CHANGENAME notifier ] [ ioctl(NETCON_REMOVE_TARGET) ] netconsole_event() move from target_list to temp list work on temp list kobject_unregister() -> release_target() -> remove_target() move back to target_list Which would mean a deleted/removed target added back => *boom* But, the race still hasn't been closed properly! You're taking the mutex only around "work on temp list" which is insufficient, you need to ensure atomicity inside netconsole_event() _completely_ like this (renaming netdev_change_sem to netdev_changename_mtx): After the target moves from target_list to temporary_list, the kobject_unregister() of possible raced target isn't called in ioctl(NETCON_REMOVE_TARGET) because the target_list doesn't contain the target . I have the wrong idea? +static char *make_netdev_class_name(char *netdev_name) +{ + char *name; + + name = kasprintf(GFP_KERNEL, "net:%s", netdev_name); Why the "net:" prefix in the filename? Because I drew upon dev_change_name() method in net/core/dev.c. The device_rename() in the above function makes use of same prefix related to netdev. static int setup_target_sysfs(struct netconsole_target *nt) { + int retval = 0; + char *name; + kobject_set_name(&nt->obj, "port%d", nt->id); nt->obj.parent = &netconsole_miscdev.this_device->kobj; nt->obj.ktype = &target_ktype; - return kobject_register(&nt->obj); + retval = kobject_register(&nt->obj); + name = make_netdev_class_name(nt->np.dev_name); + if (!name) + return -ENOMEM; Just call kasprintf() directly, why the obfuscation? I drew upon dev_change_name() method in net/core/dev.c. Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take5 6/7] add ioctls for adding/removing target
Hello Satyam, *ugh*. I was wondering what a show-stopper this particular patch was -- introduces a couple of ioctl()'s, exports a new structure to userspace, adds a hitherto-unneeded header file, brings in tty_struct/tty_operations and ends up adding so much complexity/ bloat to netconsole.c. Not only that, it must live together (and side-by-side) with the sysfs interface also, because the two of them do different things: sysfs to be able to modify target parameters at run-time and the ioctl()'s to dynamically add/remove targets. We can't really mkdir(2) or rmdir(2) in sysfs so the ioctl()'s are needed. So may I suggest: Just lose *both* the sysfs and ioctl() interfaces and use _configfs_. It is *precisely* the thing you need in your driver here -- the ability to create / destroy kernel objects (or config_items in configfs lingo) from _userspace_ via simple mkdir(2) and rmdir(2). And configfs makes changing multiple configurable parameters atomically trivial too, via rename(2) ... not to mention a sysfs+ioctls -> configfs conversion would help your patchset lose some weight too :-) Stephen Hemminger previously advised me about the user interface such as the following messages. Some other speculations: 1. Would it be possible to add ioctl's to /dev/console? This would be more in keeping with older Unix style model. 2. Using sysfs makes sense if there is a device object that exists to add the sysfs attributes to. 3. Procfs is handy for summary type tables. 4. Netlink does feel like overkill for this. Although newer generic netlink makes it easier. So, I implemented ioctls to add/remove port like this patch on the tty driver. But I'm going to search configfs. Thank you for you information. Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take5 4/7] using symlink for the net_device
Hello Satyam, Sorry, but we're not covering from the error condition fully here. Note that later you merge the temporary modify_target_list entirely back into the target_list ... which would still contain these erroneous nodes. A full cleanup (kobject_unregister the entry, and then list_del from modify_target_list) is required here, before continuing. I will fix this. If the error occurs, I think so that we need to cleanup completely. + strcpy(nt->np.dev_name, dev->name); ... you'll have move this up. Why? I don't have opposition about moving this up, but I'm misplacing the abobe code? or it isn't appropriate about coding style? Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take5 3/7] add interface for netconsole using sysfs
Hello Satyam, First, I'm sorry I couldn't reply to your comments. I'm so appreciate for your comments. I will fix my patches following your advices. But, I have some questions on the another patches. So, I want to ask you some questions and answer your questions. +static int miscdev_configured; Is this really required? We just return with error if misc_register() fails during module init time itself, so it's not really useful ever, is it? You're right. It isn't required. Thanks -- Keiichi KII NEC Corporation OSS Platform Development Division E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take5 7/7] update documentation
From: Keiichi KII <[EMAIL PROTECTED]> update Documentation/networking/netconsole.txt - how to use sysfs for dynamic configurability - how to use ioctl for dynamic configurability Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- Index: mm/Documentation/networking/netconsole.txt === --- mm.orig/Documentation/networking/netconsole.txt +++ mm/Documentation/networking/netconsole.txt @@ -4,6 +4,9 @@ started by Ingo Molnar <[EMAIL PROTECTED] Please send bug reports to Matt Mackall <[EMAIL PROTECTED]> +1. Description +-- + This module logs kernel printk messages over UDP allowing debugging of problem where disk logging fails and serial consoles are impractical. @@ -13,6 +16,21 @@ the specified interface as soon as possi capture of early kernel panics, it does capture most of the boot process. +This module equips the runtime configurability that can changes +values(src/tgt IP address and port, tgt MAC address) by using sysfs +and can add/remove logging agent by using ioctls. + +In order to use the runtime configurability, you have to enable +CONFIG_NETCONSOLE_DYNCON. If you don't use one, you don't have to enable +CONFIG_NETCONSOLE_DYNCON. By disabling this option, The kernel module +size is smaller than the module enabled CONFIG_NETCONSOLE_DYNCON. + +2. Configuration + + +2.1 Module Parameter(sender side) +- + It takes a string configuration parameter "netconsole" in the following format: @@ -34,12 +52,21 @@ Examples: insmod netconsole netconsole=@/,@10.0.0.2/ +Or it also takes a semi-colon separated configuration parameter. +In the case, you can send kerenl messages to multiple logging agents. + + netconsole=;; + + each target is the above configuration parameter. + +Examples: + + netconsole="@/,[EMAIL PROTECTED]/;@/,[EMAIL PROTECTED]/" + Built-in netconsole starts immediately after the TCP stack is initialized and attempts to bring up the supplied dev at the supplied address. -The remote host can run either 'netcat -u -l -p ' or syslogd. - WARNING: the default target ethernet setting uses the broadcast ethernet address to send packets, which can cause increased load on other systems on the same ethernet segment. @@ -55,3 +82,83 @@ from IRQ contexts as well, and does not sending packets. Due to these unique needs, configuration cannot be more automatic, and some fundamental limitations will remain: only IP networks, UDP packets and ethernet devices are supported. + +2.2 Receiver side +- + +The remote host can run either 'netcat -u -l -p ' or syslogd. + +3 Dynamic Configurability +- + +You can make use of the dynamic configurability if +CONFIG_NETCONSOLE_DYNCON is enabled. The operations are the following. + +3.1 /sys/class/misc/netconsole + +This entry, "netconsole", has the following attributes related to +netconsole. You can change configuration of netconsole(writable +attributes such as IP address, port number and so on) and check +current configuration of netconsole. + +-+- /sys/class/misc/ + |-+- netconsole/ + |-+- port1/ + | |--- enabled [rw-r--r--] 0:disable 1:enable + | |--- id [r--r--r--] unique port id + | |--- local_ip [rw-r--r--] source IP to use + | |--- local_mac[r--r--r--] source MAC address + | |--- local_port [rw-r--r--] source port number for UDP packets + | |--- net: [r--r--r--] symlink to net_dev: eth0,eth1,... + | |--- remote_ip[rw-r--r--] port number for logging agent + | |--- remote_mac [rw-r--r--] MAC address for logging agent + | +--- remote_port [rw-r--r--] IP address for logging agent + |--- port2/ + |--- port3/ + ... + +If "enabled" attribute of certain port is '1', this port is used +and the configurations of this port are uable to change. + +If "enabled" attribute of certain port is '0', this port isn't used +and the configurations of this port are able to change. + +3.2 ioctls + +1. create device file + +First of all, we would like you to check the entry, "/proc/devices", +in procfs because of creating device file for netconsole. +If you can find the entry, "netcon" and that major number, create +the device file using mknod command. + +2. send commands using ioctl system call + +You can send the following ioctl commands to the above device file. + +- NETCONSOLE_ADD_TARGET ioctl adds netconsole target + +In the case of module parameter, + + [EMAIL PROTECTED]/eth0,[EMAIL PROTECTED]/12:34:56:78:9a:bc + +In the case of ioclt command, + + struct netconsole_request req = { + .netdev_name = "eth0", + .local_ip = inet_addr("10.0.0.1"), + .local_port = 6665, + .remote_ip = inet_addr("10.0.0.2"), +
[RFC][PATCH -mm take5 6/7] add ioctls for adding/removing target
From: Keiichi KII <[EMAIL PROTECTED]> We add ioctls for adding/removing target. If we use NETCONSOLE_ADD_TARGET ioctl, we can dynamically add netconsole target. If we use NETCONSOLE_REMOVE_TARGET ioctl, we can dynamically remoe netconsole target. We attach a sample program for ioctl. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- /* * This software is a sample program for ioctl of netconsole. * You can add/remove netconsole port by using this software. * * Copyright (C) 2007 NEC Corporation * Created by Keiichi KII <[EMAIL PROTECTED]> * This software is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) any later version. */ #include #include #include #include #include #include #include #include #include #include #define NETCONSOLE_DEV_NAME "/dev/netconsole" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) struct command { char *name; char *options; int (*handle_command)(struct command* command, int argc, char* argv[]); void (*usage)(char *msg); }; extern char *optarg; extern int opterr, optind, errno; static void generic_usage(char *msg) { fprintf(stderr, "Usage : netconfig command [option] [args]\n"); fprintf(stderr, "command: add remove help\n"); exit(-1); } static int handle_command_add(struct command* command, int argc, char** argv) { int i, fd, ch; unsigned int address; unsigned char mac[ETH_ALEN]; struct netconsole_request req = { .netdev_name = "eth0", .local_port = 6665, .remote_port = , .remote_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, }; while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'p': req.local_port = atoi(optarg); break; case 's': address = inet_addr(optarg); if (address == -1) (*command->usage)("invlid IP address!\n"); req.local_ip = address; break; case 'h': default: (*command->usage)(NULL); } } argc -= optind; argv += optind; if (argc < 3 || argc > 4) (*command->usage)(NULL); memcpy(req.netdev_name, argv[0], IFNAMSIZ); address = inet_addr(argv[1]); if (address == -1) (*command->usage)("invlid IP address!\n"); req.remote_ip = address; req.remote_port = atoi(argv[2]); if (argc == 4) { i = 0; mac[i++] = strtol(argv[3], NULL, 16); while ((argv[3] = strchr(argv[3], ':')) != NULL) { argv[3]++; mac[i++] = strtol(argv[3], NULL, 16); } if (i != ETH_ALEN) (*command->usage)("Invalid MAC address!\n"); memcpy(req.remote_mac, mac, ETH_ALEN); } fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "cannot open device" NETCONSOLE_DEV_NAME "\n"); return -1; } if(ioctl(fd, NETCON_ADD_TARGET, &req) != 0) perror("add"); close(fd); return 0; } static void usage_add(char *msg) { if (msg != NULL) fprintf(stderr, "%s", msg); fprintf(stderr, "Usage : netconfig add [-options] dev_name remote_ip " "remote_port [remote_mac]\n"); fprintf(stderr, "options:\n"); fprintf(stderr, "-p local_port :local port number\n"); fprintf(stderr, "-s local_up :local IP address\n"); exit(-1); } static int handle_command_remove(struct command *command, int argc, char** argv) { int fd, id, ch; while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'h': default: (*command->usage)(NULL); } } argc -= optind; argv += optind; if (argc != 1) (*command->usage)(NULL); id = atoi(argv[0]); fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "can't open device &
[RFC][PATCH -mm take5 5/7] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are unable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -71,6 +71,7 @@ struct netconsole_target { struct list_head list; struct kobject obj; int id; + int enabled; struct netpoll np; }; @@ -121,9 +122,16 @@ static ssize_t show_remote_mac(struct ne nt->np.remote_mac[4], nt->np.remote_mac[5]); } +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->enabled); +} + static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { + if (nt->enabled) + return -EINVAL; nt->np.local_port = simple_strtol(buf, NULL, 10); return count; @@ -132,6 +140,8 @@ static ssize_t store_local_port(struct n static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, size_t count) { + if (nt->enabled) + return -EINVAL; nt->np.remote_port = simple_strtol(buf, NULL, 10); return count; @@ -140,6 +150,8 @@ static ssize_t store_remote_port(struct static ssize_t store_local_ip(struct netconsole_target *nt, const char *buf, size_t count) { + if (nt->enabled) + return -EINVAL; nt->np.local_ip = ntohl(in_aton(buf)); return count; @@ -148,6 +160,8 @@ static ssize_t store_local_ip(struct net static ssize_t store_remote_ip(struct netconsole_target *nt, const char *buf, size_t count) { + if (nt->enabled) + return -EINVAL; nt->np.remote_ip = ntohl(in_aton(buf)); return count; @@ -166,13 +180,34 @@ static ssize_t store_remote_mac(struct n cur++; input_mac[i++] = simple_strtol(cur, NULL, 16); } - if (i != ETH_ALEN) + if (i != ETH_ALEN || nt->enabled) return -EINVAL; memcpy(nt->np.remote_mac, input_mac, ETH_ALEN); return count; } +static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, + size_t count) +{ + int enabled = 0; + + if (count >= 2 && (count != 2 || buf[count - 1] != '\n')) { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } else if (buf[0] == '1') + enabled = 1; + else if (buf[0] == '0') + enabled = 0; + else { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + nt->enabled = enabled; + + return count; +} + struct target_attr { struct attribute attr; ssize_t (*show)(struct netconsole_target*, char*); @@ -196,6 +231,8 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enabled, S_IRUGO | S_IWUSR, +show_enabled, store_enabled); static struct attribute *target_attrs[] = { &target_attr_id.attr, @@ -205,6 +242,7 @@ static struct attribute *target_attrs[] &target_attr_remote_ip.attr, &target_attr_local_mac.attr, &target_attr_remote_mac.attr, + &target_attr_enabled.attr, NULL }; @@ -336,6 +374,7 @@ static int add_target(char* target_confi } new_target->id = atomic_inc_return(&target_count); + new_target->enabled = 1; printk(KERN_INFO "netconsole: add target: " "remote ip_addr=%d.%d.%d.%d remote port=%d\n", @@ -420,7 +459,8 @@ static void write_msg(struct console *co for (left = len; left; ) { frag = min(left, MAX_PRINT_CHUNK); list_for_each_entry(target, &target_list, list) - netpoll_send_udp(&target
[RFC][PATCH -mm take5 3/7] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_mac [r--r--r--] source MAC address | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_mac [rw-r--r--] MAC address for logging agent, writable | remote_port [rw-r--r--] IP address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: trunk/drivers/net/netconsole.c === --- trunk.orig/drivers/net/netconsole.c +++ trunk/drivers/net/netconsole.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -67,6 +69,7 @@ static struct netpoll np = { #ifdef CONFIG_NETCONSOLE_DYNCON struct netconsole_target { struct list_head list; + struct kobject obj; int id; struct netpoll np; }; @@ -74,6 +77,164 @@ struct netconsole_target { static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static int miscdev_configured; + +static ssize_t show_id(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->id); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + nt->np.local_port = simple_strtol(buf, NULL, 10); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + nt->np.remote_port = simple_strtol(buf, NULL, 10); + + return count; +} + +static ssize_t store_local_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ + nt->np.local_ip = ntohl(in_aton(buf)); + + return count; +} + +static ssize_t store_remote_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ + nt->np.remote_ip = ntohl(in_aton(buf)); + + return count; +} + +static ssize_t store_remote_mac(struct netconsole_target *nt, const char *buf, + size_t count) +{ + unsigned char input_mac[ETH_ALEN] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const char *cur = buf; + int i = 0; + + input_mac[i++] = simple_strtol(cur, NULL, 16); + while ((cur = strchr(cur, ':')) != NULL) { + cur++; + input_mac[i++] = simple_strtol(cur, NULL, 16); + } + if (i != ETH_ALEN) + return -EINVAL; + memcpy(nt->np.remote_mac, input_mac, ETH_ALEN); + + return count; +} + +struct target_attr { + struct attribute attr; + ssize_t (*show)(struct netconsole_target*, char*); + ssize_t (*store)(struct netconsole_target*, const char*, +
[RFC][PATCH -mm take5 4/7] using symlink for the net_device
From: Keiichi KII <[EMAIL PROTECTED]> We use symbolic link for net_device. The link in sysfs represents the corresponding network etherdevice. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- net: [r--r--r--] net_dev: eth0,eth1,... | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -76,6 +76,7 @@ struct netconsole_target { static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static DECLARE_MUTEX(netdev_change_sem); static int miscdev_configured; @@ -239,12 +240,14 @@ static void remove_target(struct netcons { unsigned long flags; + down(&netdev_change_sem); spin_lock_irqsave(&target_list_lock, flags); list_del(&nt->list); if (list_empty(&target_list)) netpoll_cleanup(&nt->np); spin_unlock_irqrestore(&target_list_lock, flags); kfree(nt); + up(&netdev_change_sem); } static void release_target(struct kobject *kobj) @@ -271,12 +274,35 @@ static struct kobj_type target_ktype = { .default_attrs = target_attrs, }; +static char *make_netdev_class_name(char *netdev_name) +{ + char *name; + + name = kasprintf(GFP_KERNEL, "net:%s", netdev_name); + if (!name) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + return NULL; + } + + return name; +} + static int setup_target_sysfs(struct netconsole_target *nt) { + int retval = 0; + char *name; + kobject_set_name(&nt->obj, "port%d", nt->id); nt->obj.parent = &netconsole_miscdev.this_device->kobj; nt->obj.ktype = &target_ktype; - return kobject_register(&nt->obj); + retval = kobject_register(&nt->obj); + name = make_netdev_class_name(nt->np.dev_name); + if (!name) + return -ENOMEM; + retval = sysfs_create_link(&nt->obj, &nt->np.dev->dev.kobj, name); + kfree(name); + + return retval; } static int add_target(char* target_config) @@ -323,6 +349,60 @@ static int add_target(char* target_confi out: return retval; } + +static int netconsole_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + int error = 0; + unsigned long flags; + char *old_link_name = NULL, *new_link_name = NULL; + struct netconsole_target *nt, *tmp; + struct net_device *dev = ptr; + LIST_HEAD(modify_target_list); + + if (event == NETDEV_CHANGENAME) { + spin_lock_irqsave(&target_list_lock, flags); + list_for_each_entry_safe(nt, tmp, &target_list, list) + if (nt->np.dev == dev) + list_move(&nt->list, &modify_target_list); + spin_unlock_irqrestore(&target_list_lock, flags); + + down(&netdev_change_sem); + list_for_each_entry(nt, &modify_target_list, list) { + new_link_name = make_netdev_class_name(dev->name); + old_link_name = make_netdev_class_name(nt->np.dev_name); + if (!new_link_name || !old_link_name) { + printk(KERN_ERR "netconsole: " + "make_netdev_class_name() failed!\n"); + kfree(new_link_name); + kfree(old_link_name); + continue; + } + sysfs_remove_link(&nt->obj, old_link_name); + error = sysfs_create_link(&nt->obj, + &nt->np.dev->dev.kobj, + new_link_name); + if (error) + printk(KERN_ERR "can't create link: %s\n", + new_link_name); + strcpy(nt->np.dev_name, dev->name); + kfree(new_link_name); + kfree(old_link_name); + } + up(&netdev_change_sem); + + spin_lock_irqsave(&target_list_lock, flags); + list_for_each_entry_safe(nt, tmp, &modify_target_list, list) + list_move(&nt->list, &target_list); + spin_unlock_irqrestore(&target_list_lock, flags); + } + + return NOTIFY_DONE; +} + +
[RFC][PATCH -mm take5 2/7] support multiple logging
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes for supporting multiple logging agents. 1. extend netconsole to multiple netpolls To send kernel messages to multiple logging agents, extend netcosnole to be able to use multiple netpolls. Each netpoll sends kernel messages to its own logging agent. 2. change config parameter format We change config parameter format from single configuration to multiple configurations separated by ';'. ex) sending kernel messages to destination1 and destination2 using eth0. modprobe netconsole \ netconsole="@/eth0,@[destination1]/;@/eth0,@[destination2]/" 3. introduce CONFIG_NETCONSOLE_DYNCON config to change between existing netconsole and netconsole applying the above function. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -61,21 +61,104 @@ static struct netpoll np = { .remote_port = , .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, }; -static int configured = 0; #define MAX_PRINT_CHUNK 1000 +#ifdef CONFIG_NETCONSOLE_DYNCON +struct netconsole_target { + struct list_head list; + int id; + struct netpoll np; +}; + +static LIST_HEAD(target_list); +static DEFINE_SPINLOCK(target_list_lock); + +static void remove_target(struct netconsole_target *nt) +{ + unsigned long flags; + + spin_lock_irqsave(&target_list_lock, flags); + list_del(&nt->list); + if (list_empty(&target_list)) + netpoll_cleanup(&nt->np); + spin_unlock_irqrestore(&target_list_lock, flags); + kfree(nt); +} + +static int add_target(char* target_config) +{ + int retval = 0; + unsigned long flags; + static atomic_t target_count = ATOMIC_INIT(0); + struct netconsole_target *new_target; + + new_target = kzalloc(sizeof(*new_target), GFP_KERNEL); + if (!new_target) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + retval = -ENOMEM; + goto out; + } + + new_target->np = np; + if (netpoll_parse_options(&new_target->np, target_config)) { + printk(KERN_ERR "netconsole: can't parse config:%s\n", + target_config); + kfree(new_target); + retval = -EINVAL; + goto out; + } + if (netpoll_setup(&new_target->np)) { + printk(KERN_ERR "netconsole: can't setup netpoll:%s\n", + target_config); + kfree(new_target); + retval = -EINVAL; + goto out; + } + + new_target->id = atomic_inc_return(&target_count); + + printk(KERN_INFO "netconsole: add target: " + "remote ip_addr=%d.%d.%d.%d remote port=%d\n", + HIPQUAD(new_target->np.remote_ip), new_target->np.remote_port); + + spin_lock_irqsave(&target_list_lock, flags); + list_add(&new_target->list, &target_list); + spin_unlock_irqrestore(&target_list_lock, flags); + + out: + return retval; +} +#endif /* CONFIG_NETCONSOLE_DYNCON */ + static void write_msg(struct console *con, const char *msg, unsigned int len) { int frag, left; unsigned long flags; +#ifdef CONFIG_NETCONSOLE_DYNCON + struct netconsole_target *target; + + if (list_empty(&target_list)) + return; + + spin_lock_irqsave(&target_list_lock, flags); + for (left = len; left; ) { + frag = min(left, MAX_PRINT_CHUNK); + list_for_each_entry(target, &target_list, list) + netpoll_send_udp(&target->np, msg, frag); + msg += frag; + left -= frag; + } + + spin_unlock_irqrestore(&target_list_lock, flags); +#else if (!np.dev) return; local_irq_save(flags); - for(left = len; left; ) { + for (left = len; left; ) { frag = min(left, MAX_PRINT_CHUNK); netpoll_send_udp(&np, msg, frag); msg += frag; @@ -83,6 +166,7 @@ static void write_msg(struct console *co } local_irq_restore(flags); +#endif /* CONFIG_NETCONSOLE_DYNCON */ } static struct console netconsole = { @@ -91,40 +175,59 @@ static struct console netconsole = { .write = write_msg }; +#ifndef MODULE static int __init option_setup(char *opt) { - configured = !netpoll_parse_options(&np, opt); + strncpy(config, opt, 256); return 1; } __setup("netconsole=", option
[RFC][PATCH -mm take5 1/7] marking __init
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following cleanups. - add __init for initialization functions(option_setup() and init_netconsole()). Acked-by: Matt Mackall <[EMAIL PROTECTED]> Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-mm/drivers/net/netconsole.c === --- linux-mm.orig/drivers/net/netconsole.c +++ linux-mm/drivers/net/netconsole.c @@ -91,7 +91,7 @@ static struct console netconsole = { .write = write_msg }; -static int option_setup(char *opt) +static int __init option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); return 1; @@ -99,7 +99,7 @@ static int option_setup(char *opt) __setup("netconsole=", option_setup); -static int init_netconsole(void) +static int __init init_netconsole(void) { int err; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take5 0/7] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to remove it and reload with different parameters. By adopting my patches, the current netconsole becomes a little complex. But the kernel messages(especially panic messages) is significant information to solve bugs and troubles promptly and we have been losing serial console port with PCs and Servers. I think that we need the environment in which we can collect kernel messages flexibly. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. [changes since take4] -change kernel base from 2.6.21-rc6-mm1 to 2.6.22-rc4-mm2. -update Documentation/networking/netconsole.txt -fix Kconfig -avoid forward-declared statics -fix coding style -use spin_lock_irqsave() and _restore() -fix race condition(netconsole_event()) -remove extra lock(write in sysfs) -change ioctl's location -use kasprintf() -error handling Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take4 2/6] support multiple logging
Well.. before you can finish this work we need to decide upon what the interface to userspace will be. - The miscdev isn't appropriate Why isn't miscdev appropriate? We just shouldn't use miscdev for networking conventionally? Yes it's rather odd, especially for networking. What does the miscdev _do_ anyway? Is it purely a target for the ioctls? Yes, I purely use miscdev for the ioctls. I want to use sysfs and ioctl to implement the dynamic configurabillity. The sysfs shows/changes netconsole configurations(IP address, port and so on). A userland application using the ioctl adds/removes netconsole port. I thought that the dynamic configurability could be realized without a userland application. in the kernel only. (e.g. only sysfs, no userland application) But I think we need the function to automatically resolve the destination MAC address from IP address because of the resolving cost and I should implement a userland application, not netconsole kernel module. The netconsle will become more useful by implementing the above function. Some other speculations: 1. Would it be possible to add ioctl's to /dev/console? This would be more in keeping with older Unix style model. 2. Using sysfs makes sense if there is a device object that exists to add the sysfs attributes to. 3. Procfs is handy for summary type tables. 4. Netlink does feel like overkill for this. Although newer generic netlink makes it easier. If I use sysfs, Is it proper location that adds each attributes of netconsole port in "/sys/class/misc/netconsole/port[0-9]*", or another locations in /sys/? Stephen Hemminger said "The configuration of netconsole's looks like the configuration of routes". I think so too. So I think ioctl commands for adding/removing port and the following userland application like route(8) command by using the ioctl. e.g. 1. add port # netconfig add 192.168.0.10 2. remove port # netconfig remove 1 3. show port info # netconfig id status Source IP Source Port Destination IP Destination Port Destination MAC 1 enable 192.168.0.1 6665192.168.0.10 00:11:22:33:44:55 2 disable 192.168.0.1 6665192.168.0.20 00:11:22:33:44:66 route(8) command uses ioctl for Netlink. But, I'm going to implement ioctl's to /dev/console because of the above comments. Thank you for your comments. Any comments very welcome. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take4 2/6] support multiple logging
We don't really have anything that corresponds to netpoll's connections at higher levels. I'm tempted to say we should make this work more like the dummy network device. ie: modprobe netconsole -o netcon1 [params] modprobe netconsole -o netcon2 [params] The configuration of netconsole's looks like the configuration of routes. Granted you probably have more routes than netconsoles, but the interface issues are similar. Netlink with a small application wouldn't be nice. And having /proc/net/netconsole (read-only) would be good for the netlink impaired. Do you say that we had better use procfs instead of sysfs to show the configurations of netconsole? If so, I have a question. I thought that "procfs use things related to process as far as possible". Is it no problem to use procfs here? -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take4 2/6] support multiple logging
On Fri, 20 Apr 2007 18:51:13 +0900 Keiichi KII <[EMAIL PROTECTED]> wrote: I started to do some cleanups and fixups here, but abandoned it when it was all getting a bit large. Here are some fixes against this patch: I'm going to fix my patches by following your reviews and send new patches on the LKML and the netdev ML in a few days. Well.. before you can finish this work we need to decide upon what the interface to userspace will be. - The miscdev isn't appropriate Why isn't miscdev appropriate? We just shouldn't use miscdev for networking conventionally? -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take4 2/6] support multiple logging
Please include an update to Documentation/networking/netconsole.txt OK, I update the documnet for the added functions in next patches. Thank you for your comments. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take4 2/6] support multiple logging
I started to do some cleanups and fixups here, but abandoned it when it was all getting a bit large. Here are some fixes against this patch: I'm going to fix my patches by following your reviews and send new patches on the LKML and the netdev ML in a few days. Thank you for your comments and reviews. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take4 0/6] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to remove it and reload with different parameters. By adopting my patches, the current netconsole becomes a little complex. But the kernel messages(especially panic messages) is significant information to solve bugs and troubles promptly and we have been losing serial console port with PCs and Servers. I think that we need the environment in which we can collect kernel messages flexibly. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. [changes since take3] -changing kernel base from 2.6.21-rc3-mm2 to 2.6.21-rc6-mm1. -introducing CONFIG_NETCONSOLE_DYNCON. -cleanup Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take4 6/6] add ioctls for adding/removing target
From: Keiichi KII <[EMAIL PROTECTED]> We add ioctls for adding/removing target. If we use NETCONSOLE_ADD_TARGET ioctl, we can dynamically add netconsole target. If we use NETCONSOLE_REMOVE_TARGET ioctl, we can dynamically remoe netconsole target. We attach a sample program for ioctl. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- /* * This software is a sample program for ioctl of netconsole. * You can add/remove netconsole port by using this software. * * Keiichi KII <[EMAIL PROTECTED]> * Copyright (C) 2007 by Keiichi KII * This software is under GPL version 2 of the license. */ #include #include #include #include #include #include #include #include #include #include #define NETCONSOLE_DEV_NAME "/dev/netconsole" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) struct command { char *name; char *options; int (*handle_command)(struct command* command, int argc, char* argv[]); void (*usage)(char *msg); }; extern char *optarg; extern int opterr, optind, errno; static void generic_usage(char *msg) { fprintf(stderr, "Usage : netconfig command [option] [args]\n"); fprintf(stderr, "command: add remove help\n"); exit(-1); } static int handle_command_add(struct command* command, int argc, char** argv) { int i, fd, ch; unsigned int address; unsigned char mac[ETH_ALEN]; struct netconsole_request req = { .netdev_name = "eth0", .local_port = 6665, .remote_port = , .remote_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, }; while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'p': req.local_port = atoi(optarg); break; case 's': address = inet_addr(optarg); if (address == -1) (*command->usage)("invlid IP address!\n"); req.local_ip = address; break; case 'h': default: (*command->usage)(NULL); } } argc -= optind; argv += optind; if (argc < 3 || argc > 4) (*command->usage)(NULL); memcpy(req.netdev_name, argv[0], IFNAMSIZ); address = inet_addr(argv[1]); if (address == -1) (*command->usage)("invlid IP address!\n"); req.remote_ip = address; req.remote_port = atoi(argv[2]); if (argc == 4) { i = 0; mac[i++] = strtol(argv[3], NULL, 16); while ((argv[3] = strchr(argv[3], ':')) != NULL) { argv[3]++; mac[i++] = strtol(argv[3], NULL, 16); } if (i != ETH_ALEN) (*command->usage)("Invalid MAC address!\n"); memcpy(req.remote_mac, mac, ETH_ALEN); } fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "cannot open device" NETCONSOLE_DEV_NAME "\n"); return -1; } if(ioctl(fd, NETCON_ADD_TARGET, &req) != 0) perror("add"); close(fd); return 0; } static void usage_add(char *msg) { if (msg != NULL) fprintf(stderr, "%s", msg); fprintf(stderr, "Usage : netconfig add [-options] dev_name remote_ip " "remote_port [remote_mac]\n"); fprintf(stderr, "options:\n"); fprintf(stderr, "-p local_port :local port number\n"); fprintf(stderr, "-s local_up :local IP address\n"); exit(-1); } static int handle_command_remove(struct command *command, int argc, char** argv) { int fd, id, ch; while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'h': default: (*command->usage)(NULL); } } argc -= optind; argv += optind; if (argc != 1) (*command->usage)(NULL); id = atoi(argv[0]); fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "can't open device " NETCONSOLE_DEV_NAME "\n"); return -1; } if(ioctl(fd, NETCON_REMOVE_TARGET, &id) != 0) perror("remove"); clo
[RFC][PATCH -mm take4 5/6] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are uable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -71,6 +71,7 @@ struct netconsole_target { struct list_head list; struct kobject obj; int id; + int enabled; struct netpoll np; }; @@ -128,10 +129,19 @@ static ssize_t show_remote_mac(struct ne nt->np.remote_mac[4], nt->np.remote_mac[5]); } +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->enabled); +} + static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -142,6 +152,10 @@ static ssize_t store_remote_port(struct size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -152,6 +166,10 @@ static ssize_t store_local_ip(struct net size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -162,6 +180,10 @@ static ssize_t store_remote_ip(struct ne size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -184,12 +206,39 @@ static ssize_t store_remote_mac(struct n if (i != ETH_ALEN) return -EINVAL; spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } memcpy(nt->np.remote_mac, input_mac, ETH_ALEN); spin_unlock(&target_list_lock); return count; } +static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, + size_t count) +{ + int enabled = 0; + + if (count >= 2 && (count != 2 || buf[count - 1] != '\n')) { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } else if (buf[0] == '1') { + enabled = 1; + } else if(buf[0] == '0') { + enabled = 0; + } else { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + spin_lock(&target_list_lock); + nt->enabled = enabled; + spin_unlock(&target_list_lock); + + return count; +} + struct target_attr { struct attribute attr; ssize_t (*show)(struct netconsole_target*, char*); @@ -213,6 +262,8 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enabled, S_IRUGO | S_IWUSR, +show_enabled, store_enabled); static struct attribute *target_attrs[] = { &target_attr_id.attr, @@ -222,6 +273,7 @@ static struct attribute *target_attrs[] &target_attr_remote_ip.attr, &target_attr_local_mac.attr, &target_attr_remote_mac.attr, + &target_attr_enabled.attr, NULL }; @@ -380,6 +432,7 @@ static int add_target(char* target_confi } new_target->id = atomic_inc_return(&target_count);
[RFC][PATCH -mm take4 4/6] using symlink for the net_device
From: Keiichi KII <[EMAIL PROTECTED]> We use symbolic link for net_device. The link in sysfs represents the corresponding network etherdevice. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- net: [rw-r--r--] net_dev: eth0,eth1,... | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -81,6 +81,9 @@ static int add_target(char* target_confi static void remove_target(struct netconsole_target *nt); static void cleanup_netconsole(void); static int setup_target_sysfs(struct netconsole_target *nt); +static char *make_netdev_class_name(char *netdev_name); +static int netconsole_event(struct notifier_block *this, unsigned long event, + void *ptr); static int miscdev_configured; @@ -274,12 +277,77 @@ static struct miscdevice netconsole_misc .name = "netconsole", }; +static struct notifier_block netconsole_notifier = { + .notifier_call = netconsole_event, +}; + static int setup_target_sysfs(struct netconsole_target *nt) { + int retval = 0; + char *name; + kobject_set_name(&nt->obj, "port%d", nt->id); nt->obj.parent = &netconsole_miscdev.this_device->kobj; nt->obj.ktype = &target_ktype; - return kobject_register(&nt->obj); + retval = kobject_register(&nt->obj); + name = make_netdev_class_name(nt->np.dev_name); + if (IS_ERR(name)) + return PTR_ERR(name); + retval = sysfs_create_link(&nt->obj, &nt->np.dev->dev.kobj, name); + kfree(name); + + return retval; +} + +static char *make_netdev_class_name(char *netdev_name) +{ + int size; + char *name; + char *netdev_class_prefix = "net:"; + + size = strlen(netdev_class_prefix) + strlen(netdev_name) + 1; + name = kmalloc(size, GFP_KERNEL); + if (!name) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + return ERR_PTR(-ENOMEM); + } + strcpy(name, netdev_class_prefix); + strcat(name, netdev_name); + + return name; +} + +static int netconsole_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + int error = 0; + char *old_link_name = NULL, *new_link_name = NULL; + struct netconsole_target *nt; + struct net_device *dev = ptr; + + if (event == NETDEV_CHANGENAME) { + spin_lock(&target_list_lock); + list_for_each_entry(nt, &target_list, list) { + if (nt->np.dev != dev) + continue; + new_link_name = make_netdev_class_name(dev->name); + old_link_name = + make_netdev_class_name(nt->np.dev_name); + sysfs_remove_link(&nt->obj, old_link_name); + error = sysfs_create_link(&nt->obj, + &nt->np.dev->dev.kobj, + new_link_name); + if (error) + printk(KERN_ERR "can't create link: %s\n", + new_link_name); + strcpy(nt->np.dev_name, dev->name); + kfree(new_link_name); + kfree(old_link_name); + } + spin_unlock(&target_list_lock); + } + + return NOTIFY_DONE; } static int add_target(char* target_config) @@ -409,6 +477,7 @@ static int __init init_netconsole(void) } else miscdev_configured = 1; + register_netdevice_notifier(&netconsole_notifier); register_console(&netconsole); if(!strlen(config)) { printk(KERN_ERR "netconsole: not configured\n"); @@ -443,6 +512,7 @@ static void cleanup_netconsole(void) list_for_each_entry_safe(nt, tmp, &target_list, list) { kobject_unregister(&nt->obj); } + unregister_netdevice_notifier(&netconsole_notifier); if (miscdev_configured) misc_deregister(&netconsole_miscdev); #else -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take4 3/6] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_mac [r--r--r--] source MAC address | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_mac [rw-r--r--] MAC address for logging agent, writable | remote_port [rw-r--r--] IP address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -67,6 +69,7 @@ static struct netpoll np = { #ifdef CONFIG_NETCONSOLE_DYNCON struct netconsole_target { struct list_head list; + struct kobject obj; int id; struct netpoll np; }; @@ -77,6 +80,207 @@ static DEFINE_SPINLOCK(target_list_lock) static int add_target(char* target_config); static void remove_target(struct netconsole_target *nt); static void cleanup_netconsole(void); +static int setup_target_sysfs(struct netconsole_target *nt); + +static int miscdev_configured; + +static ssize_t show_id(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->id); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_local_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_ip = ntohl(in_aton(buf)); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_ip = ntohl(in_aton(buf)); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_mac(struct netconsole_target *nt, const char *buf, + size_t count) +{ + unsigned char input_mac[ETH_ALEN] = + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + const char *cur = buf; + int i = 0; + + input_mac[i++] = simple_strtol(cur, NULL, 16); + while
[RFC][PATCH -mm take4 2/6] support multiple logging
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes for supporting multiple logging agents. 1. extend netconsole to multiple netpolls To send kernel messages to multiple logging agents, extend netcosnole to be able to use multiple netpolls. Each netpoll sends kernel messages to its own logging agent. 2. change config parameter format We change config parameter format from single configuration to multiple configurations separated by ';'. ex) sending kernel messages to destination1 and destination2 using eth0. modprobe netconsole \ netconsole="@/eth0,@[destination1]/;@/eth0,@[destination2]/" 3. introduce CONFIG_NETCONSOLE_DYNCON config to change between existing netconsole and netconsole applying the above function. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: mm/drivers/net/netconsole.c === --- mm.orig/drivers/net/netconsole.c +++ mm/drivers/net/netconsole.c @@ -61,15 +61,102 @@ static struct netpoll np = { .remote_port = , .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, }; -static int configured = 0; #define MAX_PRINT_CHUNK 1000 +#ifdef CONFIG_NETCONSOLE_DYNCON +struct netconsole_target { + struct list_head list; + int id; + struct netpoll np; +}; + +static LIST_HEAD(target_list); +static DEFINE_SPINLOCK(target_list_lock); + +static int add_target(char* target_config); +static void remove_target(struct netconsole_target *nt); +static void cleanup_netconsole(void); + +static int add_target(char* target_config) +{ + int retval = 0; + static atomic_t target_count = ATOMIC_INIT(0); + struct netconsole_target *new_target; + + new_target = kzalloc(sizeof(*new_target), GFP_KERNEL); + if (!new_target) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + retval = -ENOMEM; + goto out; + } + + new_target->np = np; + if (netpoll_parse_options(&new_target->np, target_config)) { + printk(KERN_ERR "netconsole: can't parse config:%s\n", + target_config); + kfree(new_target); + retval = -EINVAL; + goto out; + } + if (netpoll_setup(&new_target->np)) { + printk(KERN_ERR "netconsole: can't setup netpoll:%s\n", + target_config); + kfree(new_target); + retval = -EINVAL; + goto out; + } + + new_target->id = atomic_inc_return(&target_count); + + printk(KERN_INFO "netconsole: add target: " + "remote ip_addr=%d.%d.%d.%d remote port=%d\n", + HIPQUAD(new_target->np.remote_ip), new_target->np.remote_port); + + spin_lock(&target_list_lock); + list_add(&new_target->list, &target_list); + spin_unlock(&target_list_lock); + + out: + return retval; +} + +static void remove_target(struct netconsole_target *nt) +{ + spin_lock(&target_list_lock); + list_del(&nt->list); + if (list_empty(&target_list)) + netpoll_cleanup(&nt->np); + spin_unlock(&target_list_lock); + kfree(nt); +} +#endif /* CONFIG_NETCONSOLE_DYNCON */ + static void write_msg(struct console *con, const char *msg, unsigned int len) { int frag, left; unsigned long flags; +#ifdef CONFIG_NETCONSOLE_DYNCON + struct netconsole_target *target; + + if (list_empty(&target_list)) + return; + local_irq_save(flags); + spin_lock(&target_list_lock); + + for(left = len; left; ) { + frag = min(left, MAX_PRINT_CHUNK); + list_for_each_entry(target, &target_list, list) { + netpoll_send_udp(&target->np, msg, frag); + } + msg += frag; + left -= frag; + } + + spin_unlock(&target_list_lock); + local_irq_restore(flags); +#else if (!np.dev) return; @@ -83,6 +170,7 @@ static void write_msg(struct console *co } local_irq_restore(flags); +#endif /* CONFIG_NETCONSOLE_DYNCON */ } static struct console netconsole = { @@ -91,39 +179,60 @@ static struct console netconsole = { .write = write_msg }; +#ifndef MODULE static int __init option_setup(char *opt) { - configured = !netpoll_parse_options(&np, opt); + strncpy(config, opt, 256); return 1; } __setup("netconsole=", option_setup); +#endif static int __init init_netconsole(void) { - int err; + char *tmp = config; +#ifdef CONFIG_NETCONSOLE_DYNCON + char *p; -
[RFC][PATCH -mm take4 1/6] marking __init
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following cleanups. - add __init for initialization functions(option_setup() and init_netconsole()). Acked-by: Matt Mackall <[EMAIL PROTECTED]> Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-mm/drivers/net/netconsole.c === --- linux-mm.orig/drivers/net/netconsole.c +++ linux-mm/drivers/net/netconsole.c @@ -91,7 +91,7 @@ static struct console netconsole = { .write = write_msg }; -static int option_setup(char *opt) +static int __init option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); return 1; @@ -99,7 +99,7 @@ static int option_setup(char *opt) __setup("netconsole=", option_setup); -static int init_netconsole(void) +static int __init init_netconsole(void) { int err; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take3 6/6][resend] add ioctls for adding/removing target
Sorry, I sent the incomplete sample program. So, I send the complete one again. Any comments welcom. #include #include #include #include #include #include #include #include #include #include #define NETCONSOLE_DEV_NAME "/dev/netconsole" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) struct command { char *name; char *options; int (*handle_command)(struct command* command, int argc, char* argv[]); void (*usage)(char *msg); }; extern char *optarg; extern int opterr, optind, errno; static void generic_usage(char *msg) { fprintf(stderr, "Usage : netconfig command [option] [args]\n"); fprintf(stderr, "command: add remove help\n"); exit(-1); } static int handle_command_add(struct command* command, int argc, char** argv) { int i, fd, ch; unsigned int address; unsigned char mac[ETH_ALEN]; struct netconsole_request req = { .netdev_name = "eth0", .local_port = 6665, .remote_port = , .remote_mac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, }; while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'p': req.local_port = atoi(optarg); break; case 's': address = inet_addr(optarg); if (address == -1) (*command->usage)("invlid IP address!\n"); req.local_ip = address; break; case 'h': default: (*command->usage)(NULL); } } argc -= optind; argv += optind; if (argc < 3 || argc > 4) (*command->usage)(NULL); memcpy(req.netdev_name, argv[0], IFNAMSIZ); address = inet_addr(argv[1]); if (address == -1) (*command->usage)("invlid IP address!\n"); req.remote_ip = address; req.remote_port = atoi(argv[2]); if (argc == 4) { i = 0; mac[i++] = strtol(argv[3], NULL, 16); while ((argv[3] = strchr(argv[3], ':')) != NULL) { argv[3]++; mac[i++] = strtol(argv[3], NULL, 16); } if (i != ETH_ALEN) (*command->usage)("Invalid MAC address!\n"); memcpy(req.remote_mac, mac, ETH_ALEN); } fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "cannot open device" NETCONSOLE_DEV_NAME "\n"); return -1; } if(ioctl(fd, NETCON_ADD_TARGET, &req) != 0) perror("add"); close(fd); return 0; } static void usage_add(char *msg) { if (msg != NULL) fprintf(stderr, "%s", msg); fprintf(stderr, "Usage : netconfig add [-options] dev_name remote_ip " "remote_port [remote_mac]\n"); fprintf(stderr, "options:\n"); fprintf(stderr, "-p local_port :local port number\n"); fprintf(stderr, "-s local_up :local IP address\n"); exit(-1); } static int handle_command_remove(struct command *command, int argc, char** argv) { int fd, id, ch; while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'h': default: (*command->usage)(NULL); } } argc -= optind; argv += optind; if (argc != 1) (*command->usage)(NULL); id = atoi(argv[0]); fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "can't open device " NETCONSOLE_DEV_NAME "\n"); return -1; } if(ioctl(fd, NETCON_REMOVE_TARGET, &id) != 0) perror("remove"); close(fd); return 0; } static void usage_remove(char *msg) { fprintf(stderr, "Usage : netconfig remove id\n"); exit(-1); } static int handle_command_help(struct command *command, int argc, char** argv) { (*command->usage)(NULL); return 0; } static void usage_help(char *msg) { generic_usage(NULL); } static struct command s_commands[] = { {"add", "hp:s:", handle_command_add, usage_add}, {"remove", "hp:", handle_command_remove, usage_remove}, {"help", NULL, handle_command_help, usage_help}, }; int main(int argc, char* argv[]) { int i; struct command *command = NULL; for(i = 0; i < ARRAY_SIZE(s_commands); i++) { if (argc <= 1) break; if (strcmp(s_commands[i]
Re: [RFC][PATCH -mm take3 2/6][resend] support multiple logging
Alexey Dobriyan wrote: On 3/20/07, Keiichi KII <[EMAIL PROTECTED]> wrote: This patch contains the following changes for supporting multiple logging agents. +#define CONFIG_SEPARATOR ";" CONFIG_* is reserved for configuration options. Since you use it in only one place just use semicolon directly. Thank you for your reply. I'm going to fix this when I send patches next time. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take3 6/6][resend] add ioctls for adding/removing target
From: Keiichi KII <[EMAIL PROTECTED]> We add ioctls for adding/removing target. If we use NETCONSOLE_ADD_TARGET ioctl, we can dynamically add netconsole target. If we use NETCONSOLE_REMOVE_TARGET ioctl, we can dynamically remoe netconsole target. We attach a sample program for ioctl. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- #include #include #include #include #include #include #include #include #include #define NETCONSOLE_DEV_NAME "/dev/netconsole" struct command { char *name; char *options; int (*handle_command)(struct command* command, int argc, char* argv[]); void (*usage)(char *msg); extern char *optarg; static void generic_usage(char *msg) { fprintf(stderr, "Usage : netconfig command [option] [args]\n"); fprintf(stderr, "command: add remove help\n"); exit(-1); break; case 's': address = inet_addr(optarg); if (address == -1) (*command->usage)("invlid IP address!\n"); req.local_ip = address; break; case 'h': default: (*command->usage)(NULL); } } argc -= optind; if (i != ETH_ALEN) (*command->usage)("Invalid MAC address!\n"); memcpy(req.remote_mac, mac, ETH_ALEN); fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "cannot open device" NETCONSOLE_DEV_NAME "\n"); return -1; exit(-1); static int handle_command_remove(struct command *command, int argc, char** argv) { while ((ch = getopt(argc, argv, command->options)) != -1) { switch (ch) { case 'h': default: (*command->usage)(NULL); } } argc -= optind; if (argc != 1) id = atoi(argv[0]); fd = open(NETCONSOLE_DEV_NAME, O_RDWR); if (fd < 0) { fprintf(stderr, "can't open device " NETCONSOLE_DEV_NAME "\n"); return -1; } if(ioctl(fd, NETCON_REMOVE_TARGET, &id) != 0) perror("remove"); return 0; static void usage_remove(char *msg) { fprintf(stderr, "Usage : netconfig remove id\n"); exit(-1); static int handle_command_help(struct command *command, int argc, char** argv) { return 0; static void usage_help(char *msg) { generic_usage(NULL); break; } } if (command == NULL) generic_usage(NULL); argc--; argv++; if (command->handle_command) (*command->handle_command)(command, argc, argv); else { fprintf(stderr, "function handle_command() isn't set."); exit(-1); } return 0; } Index: linux-mm/fs/compat_ioctl.c === --- linux-mm.orig/fs/compat_ioctl.c +++ linux-mm/fs/compat_ioctl.c @@ -117,6 +117,8 @@ #include #include +#include + static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *f) { Index: linux-mm/include/linux/compat_ioctl.h === --- linux-mm.orig/include/linux/compat_ioctl.h +++ linux-mm/include/linux/compat_ioctl.h @@ -828,3 +828,6 @@ COMPATIBLE_IOCTL(VIDEO_GET_NAVI) COMPATIBLE_IOCTL(VIDEO_SET_ATTRIBUTES) COMPATIBLE_IOCTL(VIDEO_GET_SIZE) COMPATIBLE_IOCTL(VIDEO_GET_FRAME_RATE) +/* netconsole */ +COMPATIBLE_IOCTL(NETCON_ADD_TARGET) +ULONG_IOCTL(NETCON_REMOVE_TARGET) Index: linux-mm/include/linux/netconsole.h === --- /dev/null +++ linux-mm/include/linux/netconsole.h @@ -0,0 +1,18 @@ +#ifndef __NETCONSOLE_H +#define __NETCONSOLE_H + +#include +#include + +struct netconsole_request { + __u32 id; + __u8 netdev_name[IFNAMSIZ]; + __u8 remote_mac[ETH_ALEN]; + __u32 local_ip, remote_ip; + __u16 local_port, remote_port; +}; + +#define NETCON_ADD_TARGET _IOW(0xAE, 4, struct netconsole_request) +#define NETCON_REMOVE_TARGET _IOW(0xAE, 5, int) + +#endif /* __NETCONSOLE_H */ Index: linux-mm/drivers/net/netconsole.c === --- linux-mm.orig/drivers/net/netconsole.c +++ linux-mm/dr
[RFC][PATCH -mm take3 4/6][resend] using symlink for the net_device
From: Keiichi KII <[EMAIL PROTECTED]> We use symbolic link for net_device. The link in sysfs represents the corresponding network etherdevice. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- net: [rw-r--r--] net_dev: eth0,eth1,... | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-mm/drivers/net/netconsole.c === --- linux-mm.orig/drivers/net/netconsole.c +++ linux-mm/drivers/net/netconsole.c @@ -77,6 +77,9 @@ static int add_target(char* target_confi static int setup_target_sysfs(struct netconsole_target *nt); static void cleanup_netconsole(void); static void delete_target(struct netconsole_target *nt); +static char* make_netdev_class_name(char *netdev_name); +static int netconsole_event(struct notifier_block *this, unsigned long event, + void *ptr); static int miscdev_configured; @@ -275,6 +278,10 @@ static struct netpoll np = { .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, }; +static struct notifier_block netconsole_notifier = { + .notifier_call = netconsole_event, +}; + static int add_target(char* target_config) { int retval = 0; @@ -322,10 +329,20 @@ static int add_target(char* target_confi static int setup_target_sysfs(struct netconsole_target *nt) { + int retval = 0; + char *name; + kobject_set_name(&nt->obj, "port%d", nt->id); nt->obj.parent = &netconsole_miscdev.this_device->kobj; nt->obj.ktype = &target_ktype; - return kobject_register(&nt->obj); + retval = kobject_register(&nt->obj); + name = make_netdev_class_name(nt->np.dev_name); + if (IS_ERR(name)) + return PTR_ERR(name); + retval = sysfs_create_link(&nt->obj, &nt->np.dev->dev.kobj, name); + kfree(name); + + return retval; } static void delete_target(struct netconsole_target *nt) @@ -337,6 +354,57 @@ static void delete_target(struct netcons kfree(nt); } +static char* make_netdev_class_name(char *netdev_name) +{ + int size; + char *name; + char *netdev_class_prefix = "net:"; + + size = strlen(netdev_class_prefix) + strlen(netdev_name) + 1; + name = kmalloc(size, GFP_KERNEL); + if (!name) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + return ERR_PTR(-ENOMEM); + } + strcpy(name, netdev_class_prefix); + strcat(name, netdev_name); + + return name; +} + +static int netconsole_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + int error = 0; + char *old_link_name = NULL, *new_link_name = NULL; + struct netconsole_target *nt; + struct net_device *dev = ptr; + + if (event == NETDEV_CHANGENAME) { + spin_lock(&target_list_lock); + list_for_each_entry(nt, &target_list, list) { + if (nt->np.dev != dev) + continue; + new_link_name = make_netdev_class_name(dev->name); + old_link_name = + make_netdev_class_name(nt->np.dev_name); + sysfs_remove_link(&nt->obj, old_link_name); + error = sysfs_create_link(&nt->obj, + &nt->np.dev->dev.kobj, + new_link_name); + if (error) + printk(KERN_ERR "can't create link: %s\n", + new_link_name); + strcpy(nt->np.dev_name, dev->name); + kfree(new_link_name); + kfree(old_link_name); + } + spin_unlock(&target_list_lock); + } + + return NOTIFY_DONE; +} + static void write_msg(struct console *con, const char *msg, unsigned int len) { int frag, left; @@ -393,6 +461,7 @@ static int __init init_netconsole(void) miscdev_configured = 1; register_console(&netconsole); + register_netdevice_notifier(&netconsole_notifier); if(!strlen(config)) { printk(KERN_ERR "netconsole: not configured\n"); @@ -416,6 +485,7 @@ static void cleanup_netconsole(void) struct netconsole_target *nt, *tmp; unregister_console(&netconsole); + unregister_netdevice_notifier(&netconsole_notifier); list_for_each_entry_safe(nt, tmp, &target_list, list) { kobject_unregister(&nt->obj); } -- - T
[RFC][PATCH -mm take3 5/6][resend] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are uable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-2.6.19.5/drivers/net/netconsole.c === --- linux-2.6.19.5.orig/drivers/net/netconsole.c +++ linux-2.6.19.5/drivers/net/netconsole.c @@ -60,6 +60,7 @@ struct netconsole_target { struct list_head list; struct kobject obj; int id; + int enabled; struct netpoll np; }; @@ -128,10 +129,19 @@ static ssize_t show_remote_mac(struct ne nt->np.remote_mac[4], nt->np.remote_mac[5]); } +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->enabled); +} + static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -142,6 +152,10 @@ static ssize_t store_remote_port(struct size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -152,6 +166,10 @@ static ssize_t store_local_ip(struct net size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -162,6 +180,10 @@ static ssize_t store_remote_ip(struct ne size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -184,12 +206,39 @@ static ssize_t store_remote_mac(struct n if (i != ETH_ALEN) return -EINVAL; spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } memcpy(nt->np.remote_mac, input_mac, ETH_ALEN); spin_unlock(&target_list_lock); return count; } +static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, + size_t count) +{ + int enabled = 0; + + if (count >= 2 && (count != 2 || buf[count - 1] != '\n')) { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } else if (strncmp(buf, "1", 1) == 0) { + enabled = 1; + } else if(strncmp(buf, "0", 1) == 0) { + enabled = 0; + } else { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + spin_lock(&target_list_lock); + nt->enabled = enabled; + spin_unlock(&target_list_lock); + + return count; +} + #define NETCON_CLASS_ATTR(_name, _mode, _show, _store) \ struct target_attr target_attr_##_name = \ __ATTR(_name, _mode, _show, _store) @@ -206,6 +255,8 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enabled, S_IRUGO | S_IWUSR, +show_enabled, store_enabled); static struct attribute *target_attrs[] = { &target_attr_id.attr, @@ -215,6 +266,7 @@ static struct attribute *target_attrs[] &target_attr_remote_ip.attr, &target_attr_local_mac.attr, &target_attr_remote_mac.attr, + &target_attr_enabled.attr, NULL }; @@ -313,6 +365,7 @@ static i
[RFC][PATCH -mm take3 3/6][resend] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_mac [r--r--r--] source MAC address | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_mac [rw-r--r--] MAC address for logging agent, writable | remote_port [rw-r--r--] IP address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-mm/drivers/net/netconsole.c === --- linux-mm.orig/drivers/net/netconsole.c +++ linux-mm/drivers/net/netconsole.c @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -56,18 +58,215 @@ MODULE_PARM_DESC(netconsole, " netconsol struct netconsole_target { struct list_head list; + struct kobject obj; int id; struct netpoll np; }; +#define MAX_PRINT_CHUNK 1000 +#define CONFIG_SEPARATOR ";" + +struct target_attr { + struct attribute attr; + ssize_t (*show)(struct netconsole_target*, char*); + ssize_t (*store)(struct netconsole_target*, const char*, +size_t count); +}; + static int add_target(char* target_config); +static int setup_target_sysfs(struct netconsole_target *nt); static void cleanup_netconsole(void); static void delete_target(struct netconsole_target *nt); +static int miscdev_configured; + static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static ssize_t show_id(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->id); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_local_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_ip = ntohl(in_aton(buf)); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_ip = ntohl(in_aton(buf)); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_rem
[RFC][PATCH -mm take3 2/6][resend] support multiple logging
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes for supporting multiple logging agents. 1. extend netconsole to multiple netpolls To send kernel messages to multiple logging agents, extend netcosnole to be able to use multiple netpolls. Each netpoll sends kernel messages to its own logging agent. 2. change config parameter format We change config parameter format from single configuration to multiple configurations separated by ';'. ex) sending kernel messages to destination1 and destination2 using eth0. modprobe netconsole \ netconsole="@/eth0,@[destination1]/;@/eth0,@[destination2]/" Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-2.6.19.5/drivers/net/netconsole.c === --- linux-2.6.19.5.orig/drivers/net/netconsole.c +++ linux-2.6.19.5/drivers/net/netconsole.c @@ -54,6 +54,20 @@ static char config[256]; module_param_string(netconsole, config, 256, 0); MODULE_PARM_DESC(netconsole, " [EMAIL PROTECTED]/[dev],[tgt-port]@/[tgt-macaddr]\n"); +struct netconsole_target { + struct list_head list; + int id; + struct netpoll np; +}; + +static int add_target(char* target_config); +static void cleanup_netconsole(void); +static void delete_target(struct netconsole_target *nt); + +static LIST_HEAD(target_list); + +static DEFINE_SPINLOCK(target_list_lock); + static struct netpoll np = { .name = "netconsole", .dev_name = "eth0", @@ -61,27 +75,85 @@ static struct netpoll np = { .remote_port = , .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, }; -static int configured = 0; #define MAX_PRINT_CHUNK 1000 +#define CONFIG_SEPARATOR ";" + +static int add_target(char* target_config) +{ + int retval = 0; + static atomic_t target_count = ATOMIC_INIT(0); + struct netconsole_target *new_target; + + new_target = kzalloc(sizeof(*new_target), GFP_KERNEL); + if (!new_target) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + retval = -ENOMEM; + goto out; + } + + new_target->np = np; + if (netpoll_parse_options(&new_target->np, target_config)) { + printk(KERN_ERR "netconsole: can't parse config:%s\n", + target_config); + kfree(new_target); + retval = -EINVAL; + goto out; + } + if (netpoll_setup(&new_target->np)) { + printk(KERN_ERR "netconsole: can't setup netpoll:%s\n", + target_config); + kfree(new_target); + retval = -EINVAL; + goto out; + } + + atomic_inc(&target_count); + new_target->id = atomic_read(&target_count); + + printk(KERN_INFO "netconsole: add target: " + "remote ip_addr=%d.%d.%d.%d remote port=%d\n", + HIPQUAD(new_target->np.remote_ip), new_target->np.remote_port); + + spin_lock(&target_list_lock); + list_add(&new_target->list, &target_list); + spin_unlock(&target_list_lock); + + out: + return retval; +} + +static void delete_target(struct netconsole_target *nt) +{ + spin_lock(&target_list_lock); + list_del(&nt->list); + spin_unlock(&target_list_lock); + netpoll_cleanup(&nt->np); + kfree(nt); +} static void write_msg(struct console *con, const char *msg, unsigned int len) { int frag, left; unsigned long flags; + struct netconsole_target *target; - if (!np.dev) + if (list_empty(&target_list)) return; local_irq_save(flags); + spin_lock(&target_list_lock); for(left = len; left; ) { frag = min(left, MAX_PRINT_CHUNK); - netpoll_send_udp(&np, msg, frag); + list_for_each_entry(target, &target_list, list) { + netpoll_send_udp(&target->np, msg, frag); + } msg += frag; left -= frag; } + spin_unlock(&target_list_lock); local_irq_restore(flags); } @@ -91,39 +163,48 @@ static struct console netconsole = { .write = write_msg }; +#ifndef MODULE static int __init option_setup(char *opt) { - configured = !netpoll_parse_options(&np, opt); + strncpy(config, opt, 256); return 1; } __setup("netconsole=", option_setup); +#endif static int __init init_netconsole(void) { - int err; + char *p; + char *tmp = config; - if(strlen(config)) - option_setup(config)
[RFC][PATCH -mm take3 1/6][resend] marking __init
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following cleanups. - add __init for initialization functions(option_setup() and init_netconsole()). Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- Index: linux-mm/drivers/net/netconsole.c === --- linux-mm.orig/drivers/net/netconsole.c +++ linux-mm/drivers/net/netconsole.c @@ -91,7 +91,7 @@ static struct console netconsole = { .write = write_msg }; -static int option_setup(char *opt) +static int __init option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); return 1; @@ -99,7 +99,7 @@ static int option_setup(char *opt) __setup("netconsole=", option_setup); -static int init_netconsole(void) +static int __init init_netconsole(void) { int err; -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take3 0/6][resend] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to remove it and reload with different parameters. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. [changes since take2] -changing kernel base from 2.6.20-rc1-mm1 to 2.6.21-rc3.mm2. -using symbolic link for network device. -changing in part interface from sysfs to ioctl, because Stephen Hemminger advised us that it is a misuse that sysfs has the behavior with magic side effect such as adding/removing port. This patch is for linux-2.6.21-rc3-mm2 and is divided to each function. Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm take2 3/5] add interface for netconsole using sysfs
>> create a sysfs entry for netconsole in /sys/class/misc. >> This entry has elements related to netconsole as follows. >> You can change configuration of netconsole(writable attributes such as IP >> address, port number and so on) and check current configuration of >> netconsole. >> >> -+- /sys/class/misc/ >> |-+- netconsole/ >>|-+- port1/ >>| |--- id [r--r--r--] unique port id >>| |--- remove [-w---] if you write something to "remove", >>| | this port is removed. >> > IMHO this kind of "magic side effect" is a misuse of sysfs. and would > make proper locking > impossible. How do you deal with the dangling reference to the > netconsole object? I manage the reference by using a list. If you write something to "remove", firstly the port entry is removed from sysfs and then the reference is removed from the list and a resource of the port is freed. > f= open (... netconsole/port1/remove") > write(f, "", 1) > sleep(2) > write(f, "", 1) this probably would crash... > > > Maybe having a state variable/sysfs file so you could setup the port and > turn it on/off with write. You are right. When I tested above program, my machine crashed. I'm going to rethink the interface for netconsole. Thanks for your comments. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take2 5/5] add "add" element in /sys/class/misc/netconsole
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are uable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- --- linux-mm/drivers/net/netconsole.c 2006-12-26 14:19:01.481857000 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.add2006-12-25 16:45:05.121887750 +0900 @@ -335,6 +335,30 @@ static struct miscdevice netconsole_misc .name = "netconsole", }; +static ssize_t store_miscdev_add(struct class_device *cdev, + const char *buf, size_t count) +{ + char *target_param; + + target_param = kmalloc(count+1, GFP_KERNEL); + if (!target_param) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + return -ENOMEM; + } + + strcpy(target_param, buf); + if (target_param[count - 1] == '\n') + target_param[count - 1] = '\0'; + + printk(KERN_INFO "netconsole: config = [%s]\n", target_param); + add_target(target_param); + kfree(target_param); + + return count; +} + +static CLASS_DEVICE_ATTR(add, S_IWUSR, NULL, store_miscdev_add); + static struct netpoll np = { .name = "netconsole", .dev_name = "eth0", @@ -464,6 +488,9 @@ static int __init init_netconsole(void) register_console(&netconsole); + class_device_create_file(netconsole_miscdev.class, +&class_device_attr_add); + if(!strlen(config)) { printk(KERN_ERR "netconsole: not configured\n"); return 0; -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm take2 4/5] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are uable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- --- linux-mm/drivers/net/netconsole.c 2006-12-26 14:19:01.461855750 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.switch 2006-12-25 16:44:57.453408500 +0900 @@ -60,6 +60,7 @@ struct netconsole_target { struct list_head list; struct kobject obj; int id; + int enabled; struct netpoll np; }; @@ -130,10 +131,19 @@ static ssize_t show_remote_mac(struct ne nt->np.remote_mac[4], nt->np.remote_mac[5]); } +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->enabled); +} + static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -144,6 +154,10 @@ static ssize_t store_remote_port(struct size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -154,6 +168,10 @@ static ssize_t store_local_ip(struct net size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -164,6 +182,10 @@ static ssize_t store_remote_ip(struct ne size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -186,12 +208,39 @@ static ssize_t store_remote_mac(struct n cur = delim + 1; } spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } memcpy(nt->np.remote_mac, input_mac, ETH_ALEN); spin_unlock(&target_list_lock); return count; } +static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, + size_t count) +{ + int enabled = 0; + + if (count >= 2 && (count != 2 || buf[count - 1] != '\n')) { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } else if (strncmp(buf, "1", 1) == 0) { + enabled = 1; + } else if(strncmp(buf, "0", 1) == 0) { + enabled = 0; + } else { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + spin_lock(&target_list_lock); + nt->enabled = enabled; + spin_unlock(&target_list_lock); + + return count; +} + static ssize_t store_remove(struct netconsole_target *nt, const char *buf, size_t count) { @@ -216,6 +265,8 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enabled, S_IRUGO | S_IWUSR, +show_enabled, store_enabled); static NETCON_CLASS_ATTR(remove, S_IWUSR, NULL, store_remove); static struct attribute *target_attrs[] = { @@ -227,6 +278,7 @@ static struct attribute *target_attrs[] &target_attr_remote_ip.attr, &target_attr_local_mac.attr, &target_attr_remote_mac.attr, + &target_attr_enabled.attr, &target_attr_remove.attr, NULL }; @@ -242,7 +294,7 @@ static ssize_t show_target_attr(struct k
[RFC][PATCH -mm take2 3/5] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- remove [-w---] if you write something to "remove", | | this port is removed. | |--- dev_name[r--r--r--] network interface name | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- local_mac [r--r--r--] source MAC address | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_port [rw-r--r--] IP address for logging agent, writable | remote_mac [rw-r--r--] MAC address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- [changes] 1. use ETH_ALEN from if_ether.h. 2. remove initialization for static variable. 3. follow the kernel coding style. --- linux-mm/drivers/net/netconsole.c 2006-12-26 14:19:01.441854500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.sysfs 2006-12-25 16:44:49.520912750 +0900 @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -56,18 +58,231 @@ MODULE_PARM_DESC(netconsole, " netconsol struct netconsole_target { struct list_head list; + struct kobject obj; int id; struct netpoll np; }; +#define MAX_PRINT_CHUNK 1000 +#define CONFIG_SEPARATOR ";" + +struct target_attr { + struct attribute attr; + ssize_t (*show)(struct netconsole_target*, char*); + ssize_t (*store)(struct netconsole_target*, const char*, +size_t count); +}; + static int add_target(char* target_config); +static void setup_target_sysfs(struct netconsole_target *nt); static void cleanup_netconsole(void); static void delete_target(struct netconsole_target *nt); +static int miscdev_configured; + static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static ssize_t show_id(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->id); +} + +static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%s\n", nt->np.dev_name); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_local_ip(struct netconsole_target *nt, const char *buf, + size_t count) +{ +
[RFC][PATCH -mm take2 1/5] marking __init
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following cleanups. - add __init for initialization functions(option_setup() and init_netconsole()). Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- --- linux-mm/drivers/net/netconsole.c 2006-12-26 14:10:17.17709 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.cleanup2006-12-25 16:44:31.615793750 +0900 @@ -91,7 +91,7 @@ static struct console netconsole = { .write = write_msg }; -static int option_setup(char *opt) +static int __init option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); return 1; @@ -99,7 +99,7 @@ static int option_setup(char *opt) __setup("netconsole=", option_setup); -static int init_netconsole(void) +static int __init init_netconsole(void) { int err; -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH -mm take2 0/5] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to remove it and reload with different parameters. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. This patch is for linux-2.6.20-rc1-mm1 and is divided to each function. Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> Signed-off-by: Takayoshi Kochi <[EMAIL PROTECTED]> --- -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm 3/5] add interface for netconsole using sysfs
Thank you for your replies and reviews. I will follow your advices. static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); I don't understand the use of HIPQUAD() here instead of NIPQUAD(). Explain? Also, NIPQUAD_FMT (in kernel.h) uses "%u.%u.%u.%u". This should probably be the same. Or just use:NIPQUAD_FMT "\n" IP address is stored in the form of host byte order in netpoll structure. So, You can't use NIPQUAD to follow the current implementation of netpoll. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH -mm 0/5] proposal for dynamic configurable netconsole
Thank you for your comments. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. This patch is for linux-2.6.20-rc1-mm1 and is divided to each function. Your comments are very welcome. Rather than extending the existing kludge with module parameter, to sysfs. I would rather see a better API for this. Please build think about doing a better API with a basic set of ioctl's. Some additional What advantage do we use a set of ioctl's compared to sysfs? I think that sysfs is easier and more readable than the ioctl's to change configurations(IP address and port number and so on). ex) # cat /sys/class/misc/netconsole/port1/remote_ip 192.168.0.1 # echo 172.16.0.1 > /sys/class/misc/netconsole/port1/remote_ip # cat /sys/class/misc/netconsole/port1/remote_ip 172.16.0.1 And the sysfs doesn't need to create access program such as the ioctl's. If you change configurations related to netconsole through the sysfs interface, a simple script file including a set of commands such as above echo will help you set up automatically. things: - shouldn't just be IPV4 specific, should handle IPV6 as well I would like to implement handling IPV6 on demand in the future. - shouldn't specify MAC address, it can do network discovery/arp to find that when adding addresses I think a userland application would rather find target MAC address and change it through the sysfs. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm 5/5] add "add" element in /sys/class/misc/netconsole
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. To add port dynamically, create "add" element in /sys/class/misc/netconsole. ex) echo "@/eth0,@192.168.0.1/" > /sys/class/misc/netconsole/add then the port is added with the settings sending kernel messages to 192.168.0.1 using eth0 device. -+- /sys/class/misc/ |-+- netconsole/ |--- add [-w---] If you write parameter(network interface name | or one config parameter of netconsole), The |port related its config is added |--- port1/ |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. remove unneccesary cast. 2. change config parameter for "add" element. --- linux-mm/drivers/net/netconsole.c 2006-12-22 20:54:54.531679750 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.add2006-12-22 16:13:02.062716500 +0900 @@ -338,6 +338,30 @@ static struct miscdevice netconsole_misc .name = "netconsole", }; +static ssize_t store_miscdev_add(struct class_device *cdev, + const char *buf, size_t count) +{ + char *target_param; + + target_param = kmalloc(count+1, GFP_KERNEL); + if (!target_param) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + return -ENOMEM; + } + + strcpy(target_param, buf); + if (target_param[count - 1] == '\n') + target_param[count - 1] = '\0'; + + printk(KERN_INFO "netconsole: config = [%s]\n", target_param); + add_target(target_param); + kfree(target_param); + + return count; +} + +static CLASS_DEVICE_ATTR(add, S_IWUSR, NULL, store_miscdev_add); + static struct netpoll np = { .name = "netconsole", .dev_name = "eth0", @@ -467,6 +491,9 @@ static int __init init_netconsole(void) register_console(&netconsole); + class_device_create_file(netconsole_miscdev.class, +&class_device_attr_add); + if(!strlen(config)) { printk(KERN_ERR "netconsole: not configured\n"); return 0; -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH -mm 4/5] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are uable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. change active/inactive netpoll from list management to flag management. 2. change the name of switch from "enable" to "enabled". 3. return proper error value. --- linux-mm/drivers/net/netconsole.c 2006-12-22 20:54:54.495677500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.switch 2006-12-22 16:12:54.746259250 +0900 @@ -60,6 +60,7 @@ struct netconsole_target { struct list_head list; struct kobject obj; int id; + int enabled; struct netpoll np; }; @@ -131,10 +132,19 @@ static ssize_t show_remote_mac(struct ne nt->np.remote_mac[4], nt->np.remote_mac[5]); } +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->enabled); +} + static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -145,6 +155,10 @@ static ssize_t store_remote_port(struct size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -155,6 +169,10 @@ static ssize_t store_local_ip(struct net size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -165,6 +183,10 @@ static ssize_t store_remote_ip(struct ne size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -189,12 +211,39 @@ static ssize_t store_remote_mac(struct n cur = delim + 1; } spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } memcpy(nt->np.remote_mac, input_mac, MAC_ADDR_DIGIT); spin_unlock(&target_list_lock); return count; } +static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, + size_t count) +{ + int enabled = 0; + + if (count >= 2 && (count != 2 || buf[count - 1] != '\n')) { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } else if (strncmp(buf, "1", 1) == 0) { + enabled = 1; + } else if(strncmp(buf, "0", 1) == 0) { + enabled = 0; + } else { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + spin_lock(&target_list_lock); + nt->enabled = enabled; + spin_unlock(&target_list_lock); + + return count; +} + static ssize_t store_remove(struct netconsole_target *nt, const char *buf, size_t count) { @@ -219,6 +268,8 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enabled, S_IRUGO | S_IWUSR, +show_enabled, store_enabled); static NETCON_CLASS_ATTR(remove, S_IWUSR, NULL, store_remove); static struct attribute *target_attrs[] = { @@ -230,6 +281,7 @@ static struct attribute *target_attrs[] &target_attr_remote_ip.attr, &target_attr_local_mac.attr, &target_attr_remote_mac.attr, + &am
[RFC][PATCH -mm 3/5] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- remove [-w---] if you write something to "remove", | | this port is removed. | |--- dev_name[r--r--r--] network interface name | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- local_mac [r--r--r--] source MAC address | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_port [rw-r--r--] IP address for logging agent, writable | remote_mac [rw-r--r--] MAC address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. expand macro code as far as possible. 2. follow kernel coding style. 3. print proper output messeage. 4. attach proper label for printk. 5. integrate netpoll_lock and netcon_target_list_lock into common spinlock. 6. return proper error value. --- linux-mm/drivers/net/netconsole.c 2006-12-22 20:54:54.431673500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.sysfs 2006-12-22 16:12:47.925833000 +0900 @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -56,18 +58,234 @@ MODULE_PARM_DESC(netconsole, " netconsol struct netconsole_target { struct list_head list; + struct kobject obj; int id; struct netpoll np; }; +#define MAX_PRINT_CHUNK 1000 +#define CONFIG_SEPARATOR ":" +#define MAC_ADDR_DIGIT 6 + +struct target_attr { + struct attribute attr; + ssize_t (*show)(struct netconsole_target*, char*); + ssize_t (*store)(struct netconsole_target*, const char*, +size_t count); +}; + static int add_target(char* target_config); +static void setup_target_sysfs(struct netconsole_target *nt); static void cleanup_netconsole(void); static void delete_target(struct netconsole_target *nt); +static int miscdev_configured = 0; + static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static ssize_t show_id(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->id); +} + +static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%s\n", nt->np.dev_name); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_local_ip(struct netconsole_targ
[RFC][PATCH -mm 0/5] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to reload netconsole module. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. This patch is for linux-2.6.20-rc1-mm1 and is divided to each function. Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. change kernel base from 2.6.19 to 2.6.20-rc1-mm1. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 take2 5/5] add "add" element in /sys/class/misc/netconsole
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. To add port dynamically, create "add" element in /sys/class/misc/netconsole. ex) echo "@/eth0,@192.168.0.1/" > /sys/class/misc/netconsole/add then the port is added with the settings sending kernel messages to 192.168.0.1 using eth0 device. -+- /sys/class/misc/ |-+- netconsole/ |--- add [-w---] If you write parameter(network interface name | or one config parameter of netconsole), The |port related its config is added |--- port1/ |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. remove unneccesary cast. 2. change config parameter for "add" element. --- linux-2.6.19/drivers/net/netconsole.c 2006-12-21 18:39:12.719185750 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.add2006-12-21 18:39:05.046706250 +0900 @@ -338,6 +338,30 @@ static struct miscdevice netconsole_misc .name = "netconsole", }; +static ssize_t store_miscdev_add(struct class_device *cdev, + const char *buf, size_t count) +{ + char *target_param; + + target_param = kmalloc(count+1, GFP_KERNEL); + if (!target_param) { + printk(KERN_ERR "netconsole: kmalloc() failed!\n"); + return -ENOMEM; + } + + strcpy(target_param, buf); + if (target_param[count - 1] == '\n') + target_param[count - 1] = '\0'; + + printk(KERN_INFO "netconsole: config = [%s]\n", target_param); + add_target(target_param); + kfree(target_param); + + return count; +} + +static CLASS_DEVICE_ATTR(add, S_IWUSR, NULL, store_miscdev_add); + static struct netpoll np = { .name = "netconsole", .dev_name = "eth0", @@ -467,6 +491,9 @@ static int __init init_netconsole(void) register_console(&netconsole); + class_device_create_file(netconsole_miscdev.class, +&class_device_attr_add); + if(!strlen(config)) { printk(KERN_ERR "netconsole: not configured\n"); return 0; -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 take2 4/5] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. If "enabled" attribute of certain port is '1', this port is used and the configurations of this port are uable to change. If "enabled" attribute of certain port is '0', this port isn't used and the configurations of this port are able to change. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enabled [rw-r--r--] 0: disable 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. change active/inactive netpoll from list management to flag management. 2. change the name of switch from "enable" to "enabled". 3. return proper error value. --- linux-2.6.19/drivers/net/netconsole.c 2006-12-21 18:39:12.62718 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.switch 2006-12-21 18:38:58.702309750 +0900 @@ -60,6 +60,7 @@ struct netconsole_target { struct list_head list; struct kobject obj; int id; + int enabled; struct netpoll np; }; @@ -131,10 +132,19 @@ static ssize_t show_remote_mac(struct ne nt->np.remote_mac[4], nt->np.remote_mac[5]); } +static ssize_t show_enabled(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->enabled); +} + static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -145,6 +155,10 @@ static ssize_t store_remote_port(struct size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_port = simple_strtol(buf, NULL, 10); spin_unlock(&target_list_lock); @@ -155,6 +169,10 @@ static ssize_t store_local_ip(struct net size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.local_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -165,6 +183,10 @@ static ssize_t store_remote_ip(struct ne size_t count) { spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } nt->np.remote_ip = ntohl(in_aton(buf)); spin_unlock(&target_list_lock); @@ -189,12 +211,39 @@ static ssize_t store_remote_mac(struct n cur = delim + 1; } spin_lock(&target_list_lock); + if (nt->enabled) { + spin_unlock(&target_list_lock); + return -EINVAL; + } memcpy(nt->np.remote_mac, input_mac, MAC_ADDR_DIGIT); spin_unlock(&target_list_lock); return count; } +static ssize_t store_enabled(struct netconsole_target *nt, const char *buf, + size_t count) +{ + int enabled = 0; + + if (count >= 2 && (count != 2 || buf[count - 1] != '\n')) { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } else if (strncmp(buf, "1", 1) == 0) { + enabled = 1; + } else if(strncmp(buf, "0", 1) == 0) { + enabled = 0; + } else { + printk(KERN_ERR "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + spin_lock(&target_list_lock); + nt->enabled = enabled; + spin_unlock(&target_list_lock); + + return count; +} + static ssize_t store_remove(struct netconsole_target *nt, const char *buf, size_t count) { @@ -219,6 +268,8 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enabled, S_IRUGO | S_IWUSR, +show_enabled, store_enabled); static NETCON_CLASS_ATTR(remove, S_IWUSR, NULL, store_remove); static struct attribute *target_attrs[] = { @@ -230,6 +281,7 @@ static struct attribute *target_attrs[] &target_attr_remote_ip.attr, &target_attr_local_mac.attr, &target_attr_remote_mac.attr, + &target_attr_enabled.attr, &tar
[RFC][PATCH 2.6.19 take2 3/5] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- remove [-w---] if you write something to "remove", | | this port is removed. | |--- dev_name[r--r--r--] network interface name | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- local_mac [r--r--r--] source MAC address | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_port [rw-r--r--] IP address for logging agent, writable | remote_mac [rw-r--r--] MAC address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. expand macro code as far as possible. 2. follow kernel coding style. 3. print proper output messeage. 4. attach proper label for printk. 5. integrate netpoll_lock and netcon_target_list_lock into common spinlock. 6. return proper error value. --- linux-2.6.19/drivers/net/netconsole.c 2006-12-21 18:39:12.535174250 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.sysfs 2006-12-21 18:38:50.921823500 +0900 @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -56,18 +58,234 @@ MODULE_PARM_DESC(netconsole, " netconsol struct netconsole_target { struct list_head list; + struct kobject obj; int id; struct netpoll np; }; +#define MAX_PRINT_CHUNK 1000 +#define CONFIG_SEPARATOR ":" +#define MAC_ADDR_DIGIT 6 + +struct target_attr { + struct attribute attr; + ssize_t (*show)(struct netconsole_target*, char*); + ssize_t (*store)(struct netconsole_target*, const char*, +size_t count); +}; + static int add_target(char* target_config); +static void setup_target_sysfs(struct netconsole_target *nt); static void cleanup_netconsole(void); static void delete_target(struct netconsole_target *nt); +static int miscdev_configured = 0; + static LIST_HEAD(target_list); static DEFINE_SPINLOCK(target_list_lock); +static ssize_t show_id(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->id); +} + +static ssize_t show_dev_name(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%s\n", nt->np.dev_name); +} + +static ssize_t show_local_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.local_port); +} + +static ssize_t show_remote_port(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d\n", nt->np.remote_port); +} + +static ssize_t show_local_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.local_ip)); +} + +static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%d.%d.%d.%d\n", HIPQUAD(nt->np.remote_ip)); +} + +static ssize_t show_local_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.local_mac[0], nt->np.local_mac[1], + nt->np.local_mac[2], nt->np.local_mac[3], + nt->np.local_mac[4], nt->np.local_mac[5]); +} + +static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf) +{ + return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", + nt->np.remote_mac[0], nt->np.remote_mac[1], + nt->np.remote_mac[2], nt->np.remote_mac[3], + nt->np.remote_mac[4], nt->np.remote_mac[5]); +} + +static ssize_t store_local_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.local_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_target *nt, const char *buf, + size_t count) +{ + spin_lock(&target_list_lock); + nt->np.remote_port = simple_strtol(buf, NULL, 10); + spin_unlock(&target_list_lock); + + return count; +} + +static ssize_t store_local_ip(struct netconsol
[RFC][PATCH 2.6.19 take2 1/5] marking __init and remove drop initialization
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following cleanups. - add __init for initialization functions(option_setup() and init_netconsole()). - remove "drop" initialization in the netpoll structure. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- [changes] 1. stop to use anoymous enum. 2. remove unrelated changes(formatting changes). --- linux-2.6.19/drivers/net/netconsole.c 2006-12-21 18:26:04.017895000 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.cleanup2006-12-21 18:38:34.080771000 +0900 @@ -60,7 +60,6 @@ static struct netpoll np = { .local_port = 6665, .remote_port = , .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - .drop = netpoll_queue, }; static int configured = 0; @@ -92,7 +91,7 @@ static struct console netconsole = { .write = write_msg }; -static int option_setup(char *opt) +static int __init option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); return 1; @@ -100,7 +99,7 @@ static int option_setup(char *opt) __setup("netconsole=", option_setup); -static int init_netconsole(void) +static int __init init_netconsole(void) { if(strlen(config)) option_setup(config); -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 take2 0/5] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to reload netconsole module. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. This patch is for linux-2.6.19 and is divided to each function. Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH 2.6.19 2/6] support multiple logging agents
>> static struct netpoll np = { >> > .name = "netconsole", >> > .dev_name = "eth0", >> > @@ -69,23 +84,91 @@ static struct netpoll np = { >> > .drop = netpoll_queue, >> > }; > > Shouldn't this piece get dropped in this patch? > This piece isn't in -mm tree, but this piece is in 2.6.19. Which version should I follow ? >> -static int configured = 0; >> +static int add_netcon_dev(const char* target_opt) >> +{ >> +static atomic_t netcon_dev_count = ATOMIC_INIT(0); > > Hiding this inside a function seems wrong. Why do we need a count? If > we've already got a spinlock, why does it need to be atomic? > We don't have a spinlock for add_netcon_dev, because we don't need to get a spinlock for add_netcon_dev except for list operation. So, it must be atomic. >> local_irq_save(flags); >> +spin_lock(&netconsole_dev_list_lock); >> for(left = len; left; ) { >> frag = min(left, MAX_PRINT_CHUNK); >> -netpoll_send_udp(&np, msg, frag); >> +list_for_each_entry(dev, &active_netconsole_dev, list) { >> +spin_lock(&dev->netpoll_lock); >> +netpoll_send_udp(&dev->np, msg, frag); >> +spin_unlock(&dev->netpoll_lock); > > Why do we need a lock here? Why isn't the list lock sufficient? What > happens if either lock is held when we get here? > The netpoll_lock is for each structure containing information related to netpoll (remote IP address and port, local IP address and port and so on). If we don't take a spinlock for each structure, the target IP address and port number are subject to change on the way sending packets. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC][PATCH 2.6.19 0/6] proposal for dynamic configurable netconsole
Matt Mackall wrote: > On Tue, Dec 12, 2006 at 03:17:48PM +0900, Keiichi KII wrote: > > FYI, there's a robot named Dave Miller who will eventually notice your > email and scold you for not cc:ing it to netdev, claiming that he > doesn't read LKML. > Thank you for your replies and reviews. When I reflect your reviews to my modification, I'm going to also send a set of patches to netdev in a few days. -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 5/6] add "add" element in /sys/class/misc/netconsole
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. To add port dynamically, create "add" element in /sys/class/misc/netconsole. ex) 1. echo "eth0" > /sys/clas/misc/netconsole/add then the port is added with the default settings. 2. echo "@/eth0,@192.168.0.1/" > /sys/class/misc/netconsole/add then the port is added with the settings sending kernel messages to 192.168.0.1 using eth0 device. -+- /sys/class/misc/ |-+- netconsole/ |--- add [-w---] If you write parameter(network interface name | or one config parameter of netconsole), The |port related its config is added |--- port1/ |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- --- linux-2.6.19/drivers/net/netconsole.c 2006-12-06 14:37:26.874827500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.add2006-12-06 13:33:05.661516750 +0900 @@ -321,6 +321,50 @@ static struct miscdevice netcon_miscdev .name = "netconsole", }; +static ssize_t set_netconmisc_add(struct class_device *cdev, const char *buf, + size_t count) +{ + char *target; + char *target_param; + + target_param = (char*)kmalloc(count+1, GFP_ATOMIC); + if (!target_param) { + printk(KERN_INFO "netconsole: kmalloc() failed!\n"); + return -ENOMEM; + } + + strcpy(target_param, buf); + if (target_param[count - 1] == '\n') { + target_param[count - 1] = '\0'; + } + + if (dev_get_by_name(target_param)) { + printk(KERN_INFO "netconsole: device name = [%s]\n", + target_param); + target = (char*)kmalloc(MAX_CONFIG_LENGTH+1, GFP_ATOMIC); + if (!target) { + printk(KERN_INFO "netconsole: kmalloc() failed!\n"); + kfree(target_param); + return -ENOMEM; + } + sprintf(target,"@/%s,@/", target_param); + add_netcon_dev(target); + kfree(target); + } else { + printk(KERN_INFO "netconsole: config = [%s]\n", target_param); + add_netcon_dev(target_param); + } + kfree(target_param); + + return count; +} + +static CLASS_DEVICE_ATTR(add, S_IWUSR, NULL, set_netconmisc_add); + +static struct class_device_attribute *netcon_misc_attr[] = { + &class_device_attr_add, +}; + static struct netpoll np = { .name = "netconsole", .dev_name = "eth0", @@ -446,6 +490,7 @@ static int __init init_netconsole(void) { char *p; char *tmp = config; + int i = 0; if (misc_register(&netcon_miscdev)) { printk(KERN_INFO @@ -456,6 +501,11 @@ static int __init init_netconsole(void) } register_console(&netconsole); + for(i=0; i < ARRAY_SIZE(netcon_misc_attr); i++) { + class_device_create_file(netcon_miscdev.class, + netcon_misc_attr[i]); + } + if(!strlen(config)) { printk(KERN_INFO "netconsole: not configured\n"); return 0; -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 6/6] update modification history
From: Keiichi KII <[EMAIL PROTECTED]> Update modification history. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- --- linux-2.6.19/drivers/net/netconsole.c 2006-12-12 14:57:45.588967500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.sign 2006-12-12 14:54:49.541965250 +0900 @@ -15,6 +15,9 @@ * generic card hooks * works non-modular * 2003-09-07rewritten with netpoll api + * 2006-12-12add extended features for + * dynamic configurable netconsole + * by Keiichi KII <[EMAIL PROTECTED]> */ /******** -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 3/6] add interface for netconsole using sysfs
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following changes. create a sysfs entry for netconsole in /sys/class/misc. This entry has elements related to netconsole as follows. You can change configuration of netconsole(writable attributes such as IP address, port number and so on) and check current configuration of netconsole. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] unique port id | |--- remove [-w---] if you write something to "remove", | | this port is removed. | |--- dev_name[r--r--r--] network interface name | |--- local_ip[rw-r--r--] source IP to use, writable | |--- local_port [rw-r--r--] source port number for UDP packets, writable | |--- local_mac [r--r--r--] source MAC address | |--- remote_ip [rw-r--r--] port number for logging agent, writable | |--- remote_port [rw-r--r--] IP address for logging agent, writable | remote_mac [rw-r--r--] MAC address for logging agent, writable |--- port2/ |--- port3/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- --- linux-2.6.19/drivers/net/netconsole.c 2006-12-06 14:37:26.842825500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.sysfs 2006-12-06 13:32:47.488381000 +0900 @@ -45,6 +45,8 @@ #include #include #include +#include +#include MODULE_AUTHOR("Maintainer: Matt Mackall <[EMAIL PROTECTED]>"); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -53,6 +55,7 @@ MODULE_LICENSE("GPL"); enum { MAX_PRINT_CHUNK = 1000, MAX_CONFIG_LENGTH = 256, + MAC_ADDR_DIGIT = 6, }; static char config[MAX_CONFIG_LENGTH]; @@ -62,19 +65,214 @@ MODULE_PARM_DESC(netconsole, " netconsol struct netconsole_device { struct list_head list; + struct kobject obj; spinlock_t netpoll_lock; int id; struct netpoll np; }; +struct netcon_dev_attr { + struct attribute attr; + ssize_t (*show)(struct netconsole_device*, char*); + ssize_t (*store)(struct netconsole_device*, const char*, +size_t count); +}; + static int add_netcon_dev(const char*); +static void setup_netcon_dev_sysfs(struct netconsole_device*); static void cleanup_netconsole(void); static void netcon_dev_cleanup(struct netconsole_device *nd); +static int netcon_miscdev_configured = 0; + static LIST_HEAD(active_netconsole_dev); static DEFINE_SPINLOCK(netconsole_dev_list_lock); +#define SHOW_CLASS_ATTR(field, type, format, ...) \ +static ssize_t show_##field(type, char *buf) \ +{ \ + return sprintf(buf, format, __VA_ARGS__); \ +} \ + +SHOW_CLASS_ATTR(id, struct netconsole_device *nd, "%d\n", nd->id); +SHOW_CLASS_ATTR(dev_name, struct netconsole_device *nd, + "%s\n", nd->np.dev_name); +SHOW_CLASS_ATTR(local_port, struct netconsole_device *nd, + "%d\n", nd->np.local_port); +SHOW_CLASS_ATTR(remote_port, struct netconsole_device *nd, + "%d\n", nd->np.remote_port); +SHOW_CLASS_ATTR(local_ip, struct netconsole_device *nd, + "%d.%d.%d.%d\n", HIPQUAD(nd->np.local_ip)); +SHOW_CLASS_ATTR(remote_ip, struct netconsole_device *nd, + "%d.%d.%d.%d\n", HIPQUAD(nd->np.remote_ip)); +SHOW_CLASS_ATTR(local_mac, struct netconsole_device *nd, + "%02x:%02x:%02x:%02x:%02x:%02x\n", + nd->np.local_mac[0], nd->np.local_mac[1], nd->np.local_mac[2], + nd->np.local_mac[3], nd->np.local_mac[4], nd->np.local_mac[5]); +SHOW_CLASS_ATTR(remote_mac, struct netconsole_device *nd, + "%02x:%02x:%02x:%02x:%02x:%02x\n", + nd->np.remote_mac[0], nd->np.remote_mac[1], + nd->np.remote_mac[2], nd->np.remote_mac[3], + nd->np.remote_mac[4], nd->np.remote_mac[5]); + +static ssize_t store_local_port(struct netconsole_device *nd, const char *buf, + size_t count) +{ + spin_lock(&nd->netpoll_lock); + nd->np.local_port = simple_strtol(buf, NULL, 10); + spin_unlock(&nd->netpoll_lock); + + return count; +} + +static ssize_t store_remote_port(struct netconsole_device *nd, const char *buf, + size_t count) +{ + spin_lock(&nd->netpoll_lock); + nd->np.remote_port = simple_strtol(buf, NULL, 10); + spin_unlock(&nd->netpoll_lock); + + return count; +} + +static ssize_t store_local_ip(struct netconsole_device *nd, const char *buf, + size_t count) +{ + spin_lock(&nd->netpoll_lock); + nd->np.local_ip = ntohl(in_aton(buf)); + spin_unlock(&nd->netpoll_lock); + + return count; +} + +static ssize_t store
[RFC][PATCH 2.6.19 4/6] switch function of netpoll
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains switch function of netpoll. if "enable" attribute of certain port is '1', this port is used. if "enable" attribute of certain port is '0', this port isn't used. active_netconsole_dev list manages a list of active ports. inactive_netconsole_dev list manages a list of inactive ports. If you write '0' to "enable" attribute of a port included in active_netconsole_dev_list, This port moves from active_netconsole_dev to inactive_netconsole_dev and won't used to send kernel message. -+- /sys/class/misc/ |-+- netconsole/ |-+- port1/ | |--- id [r--r--r--] id | |--- enable [rw-r--r--] 0: disable, 1: enable, writable | ... |--- port2/ ... Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- --- linux-2.6.19/drivers/net/netconsole.c 2006-12-06 14:37:26.858826500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.switch 2006-12-06 13:32:56.744959500 +0900 @@ -86,9 +86,25 @@ static void netcon_dev_cleanup(struct ne static int netcon_miscdev_configured = 0; static LIST_HEAD(active_netconsole_dev); +static LIST_HEAD(inactive_netconsole_dev); static DEFINE_SPINLOCK(netconsole_dev_list_lock); +static ssize_t show_enable(struct netconsole_device *nd, char *buf) { + struct netconsole_device *dev; + + spin_lock(&netconsole_dev_list_lock); + list_for_each_entry(dev, &active_netconsole_dev, list) { + if (dev->id == nd->id) { + spin_unlock(&netconsole_dev_list_lock); + return sprintf(buf, "1\n"); + } + } + spin_unlock(&netconsole_dev_list_lock); + + return sprintf(buf, "0\n"); +} + #define SHOW_CLASS_ATTR(field, type, format, ...) \ static ssize_t show_##field(type, char *buf) \ { \ @@ -180,6 +196,36 @@ static ssize_t store_remote_mac(struct n return count; } +static ssize_t store_enable(struct netconsole_device *nd, const char *buf, + size_t count) +{ + struct netconsole_device *dev, *tmp; + struct list_head *src, *dst; + + if (strncmp(buf, "1", 1) == 0) { + src = &inactive_netconsole_dev; + dst = &active_netconsole_dev; + } else if(strncmp(buf, "0", 1) == 0) { + src = &active_netconsole_dev; + dst = &inactive_netconsole_dev; + } else { + printk(KERN_INFO "netconsole: invalid argument: %s\n", buf); + return -EINVAL; + } + + spin_lock(&netconsole_dev_list_lock); + list_for_each_entry_safe(dev, tmp, src, list) { + if (dev->id == nd->id) { + list_del(&nd->list); + list_add(&nd->list, dst); + break; + } + } + spin_unlock(&netconsole_dev_list_lock); + + return count; +} + static ssize_t store_remove(struct netconsole_device *nd, const char *buf, size_t count) { @@ -204,6 +250,7 @@ static NETCON_CLASS_ATTR(remote_ip, S_IR static NETCON_CLASS_ATTR(local_mac, S_IRUGO, show_local_mac, NULL); static NETCON_CLASS_ATTR(remote_mac, S_IRUGO | S_IWUSR, show_remote_mac, store_remote_mac); +static NETCON_CLASS_ATTR(enable, S_IRUGO | S_IWUSR, show_enable, store_enable); static NETCON_CLASS_ATTR(remove, S_IWUSR, NULL, store_remove); static struct attribute *netcon_dev_attrs[] = { @@ -215,6 +262,7 @@ static struct attribute *netcon_dev_attr &netcon_dev_attr_remote_ip.attr, &netcon_dev_attr_local_mac.attr, &netcon_dev_attr_remote_mac.attr, + &netcon_dev_attr_enable.attr, &netcon_dev_attr_remove.attr, NULL }; @@ -434,6 +482,9 @@ static void cleanup_netconsole(void) list_for_each_entry_safe(dev, tmp, &active_netconsole_dev, list) { kobject_unregister(&dev->obj); } + list_for_each_entry_safe(dev, tmp, &inactive_netconsole_dev, list) { + kobject_unregister(&dev->obj); + } if (netcon_miscdev_configured) { misc_deregister(&netcon_miscdev); -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 1/6] cleanup for netconsole
From: Keiichi KII <[EMAIL PROTECTED]> This patch contains the following cleanups. - add __init for initialization functions(option_setup() and init_netconsole()). - define name of magic number. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- --- linux-2.6.19/drivers/net/netconsole.c 2006-12-06 14:37:06.985584500 +0900 +++ enhanced-netconsole/drivers/net/netconsole.c.cleanup2006-12-06 14:34:52.561183500 +0900 @@ -50,8 +50,14 @@ MODULE_AUTHOR("Maintainer: Matt Mackall MODULE_DESCRIPTION("Console driver for network interfaces"); MODULE_LICENSE("GPL"); -static char config[256]; -module_param_string(netconsole, config, 256, 0); +enum { + MAX_PRINT_CHUNK = 1000, + MAX_CONFIG_LENGTH = 256, +}; + +static char config[MAX_CONFIG_LENGTH]; + +module_param_string(netconsole, config, MAX_CONFIG_LENGTH, 0); MODULE_PARM_DESC(netconsole, " [EMAIL PROTECTED]/[dev],[tgt-port]@/[tgt-macaddr]\n"); static struct netpoll np = { @@ -62,9 +68,8 @@ static struct netpoll np = { .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, .drop = netpoll_queue, }; -static int configured = 0; -#define MAX_PRINT_CHUNK 1000 +static int configured = 0; static void write_msg(struct console *con, const char *msg, unsigned int len) { @@ -75,14 +80,12 @@ static void write_msg(struct console *co return; local_irq_save(flags); - for(left = len; left; ) { frag = min(left, MAX_PRINT_CHUNK); netpoll_send_udp(&np, msg, frag); msg += frag; left -= frag; } - local_irq_restore(flags); } @@ -92,7 +95,7 @@ static struct console netconsole = { .write = write_msg }; -static int option_setup(char *opt) +static int __init option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); return 1; @@ -100,7 +103,7 @@ static int option_setup(char *opt) __setup("netconsole=", option_setup); -static int init_netconsole(void) +static int __init init_netconsole(void) { if(strlen(config)) option_setup(config); -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[RFC][PATCH 2.6.19 0/6] proposal for dynamic configurable netconsole
From: Keiichi KII <[EMAIL PROTECTED]> The netconsole is a very useful module for collecting kernel message under certain circumstances(e.g. disk logging fails, serial port is unavailable). But current netconsole is not flexible. For example, if you want to change ip address for logging agent, in the case of built-in netconsole, you can't change config except for changing boot parameter and rebooting your system, or in the case of module netconsole, you need to reload netconsole module. So, I propose the following extended features for netconsole. 1) support for multiple logging agents. 2) add interface to access each parameter of netconsole using sysfs. This patch is for linux-2.6.19 and is divided to each function. Your comments are very welcome. Signed-off-by: Keiichi KII <[EMAIL PROTECTED]> --- -- Keiichi KII NEC Corporation OSS Promotion Center E-mail: [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/