|
@@ -124,6 +124,30 @@ static int kobj_usermode_filter(struct kobject *kobj)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int init_uevent_argv(struct kobj_uevent_env *env, const char *subsystem)
|
|
|
+{
|
|
|
+ int len;
|
|
|
+
|
|
|
+ len = strlcpy(&env->buf[env->buflen], subsystem,
|
|
|
+ sizeof(env->buf) - env->buflen);
|
|
|
+ if (len >= (sizeof(env->buf) - env->buflen)) {
|
|
|
+ WARN(1, KERN_ERR "init_uevent_argv: buffer size too small\n");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ env->argv[0] = uevent_helper;
|
|
|
+ env->argv[1] = &env->buf[env->buflen];
|
|
|
+ env->argv[2] = NULL;
|
|
|
+
|
|
|
+ env->buflen += len + 1;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void cleanup_uevent_env(struct subprocess_info *info)
|
|
|
+{
|
|
|
+ kfree(info->data);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* kobject_uevent_env - send an uevent with environmental data
|
|
|
*
|
|
@@ -301,11 +325,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|
|
|
|
|
/* call uevent_helper, usually only enabled during early boot */
|
|
|
if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {
|
|
|
- char *argv [3];
|
|
|
+ struct subprocess_info *info;
|
|
|
|
|
|
- argv [0] = uevent_helper;
|
|
|
- argv [1] = (char *)subsystem;
|
|
|
- argv [2] = NULL;
|
|
|
retval = add_uevent_var(env, "HOME=/");
|
|
|
if (retval)
|
|
|
goto exit;
|
|
@@ -313,9 +334,18 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
|
|
|
"PATH=/sbin:/bin:/usr/sbin:/usr/bin");
|
|
|
if (retval)
|
|
|
goto exit;
|
|
|
+ retval = init_uevent_argv(env, subsystem);
|
|
|
+ if (retval)
|
|
|
+ goto exit;
|
|
|
|
|
|
- retval = call_usermodehelper(argv[0], argv,
|
|
|
- env->envp, UMH_WAIT_EXEC);
|
|
|
+ retval = -ENOMEM;
|
|
|
+ info = call_usermodehelper_setup(env->argv[0], env->argv,
|
|
|
+ env->envp, GFP_KERNEL,
|
|
|
+ NULL, cleanup_uevent_env, env);
|
|
|
+ if (info) {
|
|
|
+ retval = call_usermodehelper_exec(info, UMH_NO_WAIT);
|
|
|
+ env = NULL; /* freed by cleanup_uevent_env */
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
exit:
|