lkml.org 
[lkml]   [2010]   [Jan]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] [8/9] SYSCTL: Convert hotplug helper string to proc_rcu_string()
    Date

    This avoids races with lockless sysctl.

    Also saves ~220 bytes in the data segment for default kernels.

    I also moved the code into a separate function because the original
    was very long.

    Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
    Signed-off-by: Andi Kleen <ak@linux.intel.com>

    ---
    include/linux/kobject.h | 2 -
    kernel/sysctl.c | 2 -
    lib/kobject_uevent.c | 50 ++++++++++++++++++++++++++++++------------------
    3 files changed, 34 insertions(+), 20 deletions(-)

    Index: linux-2.6.33-rc2-ak/include/linux/kobject.h
    ===================================================================
    --- linux-2.6.33-rc2-ak.orig/include/linux/kobject.h
    +++ linux-2.6.33-rc2-ak/include/linux/kobject.h
    @@ -31,7 +31,7 @@
    #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */

    /* path to the userspace helper executed on an event */
    -extern char uevent_helper[];
    +extern char *uevent_helper;

    /* counter to tag the uevent, read only except for the kobject core */
    extern u64 uevent_seqnum;
    Index: linux-2.6.33-rc2-ak/kernel/sysctl.c
    ===================================================================
    --- linux-2.6.33-rc2-ak.orig/kernel/sysctl.c
    +++ linux-2.6.33-rc2-ak/kernel/sysctl.c
    @@ -551,7 +551,7 @@ static struct ctl_table kern_table[] = {
    .data = &uevent_helper,
    .maxlen = UEVENT_HELPER_PATH_LEN,
    .mode = 0644,
    - .proc_handler = proc_dostring,
    + .proc_handler = proc_rcu_string,
    },
    #endif
    #ifdef CONFIG_CHR_DEV_SG
    Index: linux-2.6.33-rc2-ak/lib/kobject_uevent.c
    ===================================================================
    --- linux-2.6.33-rc2-ak.orig/lib/kobject_uevent.c
    +++ linux-2.6.33-rc2-ak/lib/kobject_uevent.c
    @@ -22,11 +22,12 @@
    #include <linux/socket.h>
    #include <linux/skbuff.h>
    #include <linux/netlink.h>
    +#include <linux/rcustring.h>
    #include <net/sock.h>


    u64 uevent_seqnum;
    -char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
    +char *uevent_helper = CONFIG_UEVENT_HELPER_PATH;
    static DEFINE_SPINLOCK(sequence_lock);
    #if defined(CONFIG_NET)
    static struct sock *uevent_sock;
    @@ -76,6 +77,34 @@ out:
    return ret;
    }

    +/* Call an external helper executable. */
    +static int uevent_call_helper(const char *subsystem, struct kobj_uevent_env *env)
    +{
    + char *argv[3];
    + char *helper;
    + int retval;
    +
    + helper = access_rcu_string(&uevent_helper, UEVENT_HELPER_PATH_LEN, GFP_KERNEL);
    + if (!helper)
    + return -ENOMEM;
    +
    + retval = -E2BIG;
    + argv[0] = helper;
    + argv[1] = (char *)subsystem;
    + argv[2] = NULL;
    + retval = add_uevent_var(env, "HOME=/");
    + if (retval)
    + goto error;
    + retval = add_uevent_var(env, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
    + if (retval)
    + goto error;
    +
    + retval = call_usermodehelper(argv[0], argv, env->envp, UMH_WAIT_EXEC);
    +error:
    + kfree(helper);
    + return retval;
    +}
    +
    /**
    * kobject_uevent_env - send an uevent with environmental data
    *
    @@ -243,23 +272,8 @@ int kobject_uevent_env(struct kobject *k
    #endif

    /* call uevent_helper, usually only enabled during early boot */
    - if (uevent_helper[0]) {
    - char *argv [3];
    -
    - argv [0] = uevent_helper;
    - argv [1] = (char *)subsystem;
    - argv [2] = NULL;
    - retval = add_uevent_var(env, "HOME=/");
    - if (retval)
    - goto exit;
    - retval = add_uevent_var(env,
    - "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
    - if (retval)
    - goto exit;
    -
    - retval = call_usermodehelper(argv[0], argv,
    - env->envp, UMH_WAIT_EXEC);
    - }
    + if (uevent_helper[0])
    + retval = uevent_call_helper(subsystem, env);

    exit:
    kfree(devpath);

    \
     
     \ /
      Last update: 2010-01-05 03:19    [W:3.852 / U:0.620 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site