lkml.org 
[lkml]   [2006]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [Patch -mm 2/5] driver core: Introduce device_move(): move a device to a new parent.
On Wed, 15 Nov 2006 11:11:36 +0100,
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> On Wed, 15 Nov 2006 10:31:59 +0100,
> Kay Sievers <kay.sievers@vrfy.org> wrote:
>
> > We need the old DEVPATH in the environment (or something similar),
> > otherwise we can't connect the event with the new device location to the
> > current device. :)
>
> Duh. I've attached another completely untested patch below.

And this one may have an actual chance of doing something useful :/

---
include/linux/kobject.h | 6 ++++++
lib/kobject.c | 17 +++++++++++++++++
lib/kobject_uevent.c | 40 ++++++++++++++++++++++++++++++++--------
3 files changed, 55 insertions(+), 8 deletions(-)

--- linux-2.6-CH.orig/include/linux/kobject.h
+++ linux-2.6-CH/include/linux/kobject.h
@@ -47,6 +47,7 @@ enum kobject_action {
KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */
KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */
KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */
+ KOBJ_MOVE = (__force kobject_action_t) 0x08, /* device move */
};

struct kobject {
@@ -265,6 +266,8 @@ extern int __must_check subsys_create_fi

#if defined(CONFIG_HOTPLUG)
void kobject_uevent(struct kobject *kobj, enum kobject_action action);
+void kobject_uevent_extended(struct kobject *kobj, enum kobject_action action,
+ const char *string);

int add_uevent_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
@@ -272,6 +275,9 @@ int add_uevent_var(char **envp, int num_
__attribute__((format (printf, 7, 8)));
#else
static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { }
+static inline void kobject_uevent_extended(struct kobject *kobj,
+ enum kobject_action action,
+ const char *string) { }

static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
--- linux-2.6-CH.orig/lib/kobject.c
+++ linux-2.6-CH/lib/kobject.c
@@ -364,6 +364,8 @@ int kobject_move(struct kobject *kobj, s
{
int error;
struct kobject *old_parent;
+ const char *devpath = NULL;
+ char *devpath_string = NULL;

kobj = kobject_get(kobj);
if (!kobj)
@@ -373,14 +375,29 @@ int kobject_move(struct kobject *kobj, s
error = -EINVAL;
goto out;
}
+ /* old object path */
+ devpath = kobject_get_path(kobj, GFP_KERNEL);
+ if (!devpath) {
+ error = -ENOMEM;
+ goto out;
+ }
+ devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
+ if (!devpath_string) {
+ error = -ENOMEM;
+ goto out;
+ }
+ sprintf(devpath_string, "OLD_DEVPATH=%s", devpath);
error = sysfs_move_dir(kobj, new_parent);
if (error)
goto out;
old_parent = kobj->parent;
kobj->parent = new_parent;
kobject_put(old_parent);
+ kobject_uevent_extended(kobj, KOBJ_MOVE, devpath);
out:
kobject_put(kobj);
+ kfree(devpath_string);
+ kfree(devpath);
return error;
}

--- linux-2.6-CH.orig/lib/kobject_uevent.c
+++ linux-2.6-CH/lib/kobject_uevent.c
@@ -50,18 +50,15 @@ static char *action_to_string(enum kobje
return "offline";
case KOBJ_ONLINE:
return "online";
+ case KOBJ_MOVE:
+ return "move";
default:
return NULL;
}
}

-/**
- * kobject_uevent - notify userspace by ending an uevent
- *
- * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
- * @kobj: struct kobject that the action is happening to
- */
-void kobject_uevent(struct kobject *kobj, enum kobject_action action)
+static void do_kobject_uevent(struct kobject *kobj, enum kobject_action action,
+ const char *string)
{
char **envp;
char *buffer;
@@ -134,7 +131,10 @@ void kobject_uevent(struct kobject *kobj
scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
envp [i++] = scratch;
scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
-
+ if (string != NULL) {
+ envp [i++] = scratch;
+ scratch += sprintf(scratch, "%s", string) + 1;
+ }
/* just reserve the space, overwrite it after kset call has returned */
envp[i++] = seq_buff = scratch;
scratch += strlen("SEQNUM=18446744073709551616") + 1;
@@ -200,9 +200,33 @@ exit:
kfree(envp);
return;
}
+
+/**
+ * kobject_uevent - notify userspace by ending an uevent
+ *
+ * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
+ * @kobj: struct kobject that the action is happening to
+ */
+void kobject_uevent(struct kobject *kobj, enum kobject_action action)
+{
+ do_kobject_uevent(kobj, action, NULL);
+}
EXPORT_SYMBOL_GPL(kobject_uevent);

/**
+ * kobject_uevent_extended - send an uevent with extended data
+ *
+ * @action: action that is happening (usually KOBJ_MOVE)
+ * @kobj: struct kobject that the action is happening to
+ * @string: string containing additional data
+ */
+void kobject_uevent_extended(struct kobject *kobj, enum kobject_action action,
+ const char *string)
+{
+ do_kobject_uevent(kobj, action, string);
+}
+
+/**
* add_uevent_var - helper for creating event variables
* @envp: Pointer to table of environment variables, as passed into
* uevent() method.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2006-11-15 18:41    [W:1.014 / U:0.008 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site