{"id":292692,"date":"2024-08-21T05:37:39","date_gmt":"2024-08-20T21:37:39","guid":{"rendered":"https:\/\/lrxjmw.cn\/uxjkztgbtzyn.html"},"modified":"2024-08-21T05:37:39","modified_gmt":"2024-08-20T21:37:39","slug":"uxjkztgbtzyn","status":"publish","type":"post","link":"https:\/\/lrxjmw.cn\/uxjkztgbtzyn.html","title":{"rendered":"Uevent \u8be6\u89e3\uff1aKobject \u72b6\u6001\u6539\u53d8\u901a\u77e5\u4e0e\u5185\u6838\u4e2d\u7684\u4f4d\u7f6e\u53ca\u5185\u90e8\u903b\u8f91\u89e3\u6790"},"content":{"rendered":"

1.Uevent\u7684\u529f\u80fd<\/p>\n

Uevent\u662fKobject\u7684\u4e00\u90e8\u4efdlinux \u8bbe\u5907\u9a71\u52a8<\/strong>\uff0c\u7528\u4e8e\u5728Kobject\u72b6\u6001\u53d1\u751f\u6539\u53d8\u65f6\uff0c\u6bd4\u5982\u964d\u4f4e\u3001\u79fb\u9664\u7b49\uff0c\u901a\u77e5\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u3002\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u6536\u5230\u8fd9\u6837\u7684\u98ce\u6ce2\u540e\uff0c\u4f1a\u505a\u76f8\u5e94\u7684\u5904\u7406\u3002<\/p>\n

2.Uevent\u5728kernel\u4e2d\u7684\u4f4d\u7f6e<\/p>\n

\u4e0b\u8fb9\u56fe\u7247\u63cf\u8ff0\u4e86Uevent\u6a21\u5757\u5728\u5185\u6838\u4e2d\u7684\u4f4d\u7f6e\uff1a<\/p>\n

\u9a71\u52a8\u8bbe\u5907\u65e0\u6cd5\u542f\u52a8\u4ee3\u780110_\u9a71\u52a8\u8bbe\u5907\u6709\u95ee\u9898\u4ee3\u780143_linux \u8bbe\u5907\u9a71\u52a8<\/p>\n

3.Uevent\u7684\u5185\u90e8\u903b\u8f91\u89e3\u67903.1SourceCode\u4f4d\u7f6e<\/p>\n

Uevent\u7684\u4ee3\u7801\u6bd4\u8f83\u7b80\u5355\uff0c\u4e3b\u8981\u6d89\u53cakobject.h\u548ckobject_uevent.c\u4e24\u4e2a\u6587\u4ef6\uff0c\u5982\u4e0b\uff1a<\/p>\n

\u9a71\u52a8\u8bbe\u5907\u65e0\u6cd5\u542f\u52a8\u4ee3\u780110_linux \u8bbe\u5907\u9a71\u52a8_\u9a71\u52a8\u8bbe\u5907\u6709\u95ee\u9898\u4ee3\u780143<\/p>\n

3.2\u6570\u636e\u7ed3\u6784\u63cf\u8ff0<\/p>\n

kobject.h\u5b9a\u4e49\u4e86uevent\u76f8\u5173\u7684\u5e38\u91cf\u548c\u6570\u636e\u7ed3\u6784\uff0c\u5982\u4e0b\uff1a<\/p>\n

\n

\/* include\/linux\/kobject.h, line 50 *\/\nenum kobject_action { \nKOBJ_ADD,\nKOBJ_REMOVE, \nKOBJ_CHANGE, \nKOBJ_MOVE,\nKOBJ_ONLINE, \nKOBJ_OFFLINE,\nKOBJ_MAX \n};\n<\/pre>\n<\/p>\n

kobject_action\u5b9a\u4e49\u4e86event\u7684\u7c7b\u578b\uff0c\u5305\u62ec\uff1a<\/p>\n

ADD\/REMOVE\uff0cKobject\uff08\u6216\u4e0b\u5c42\u6570\u636e\u7ed3\u6784\uff09\u7684\u6dfb\u52a0\/\u79fb\u9664\u98ce\u6ce2\u3002<\/p>\n

ONLINE\/OFFLINE\uff0cKobject\uff08\u6216\u4e0b\u5c42\u6570\u636e\u7ed3\u6784\uff09\u7684\u4e0a\u7ebf\/\u4e0b\u7ebf\u98ce\u6ce2\uff0c\u867d\u7136\u662f\u662f\u5426\u4f7f\u80fd\u3002<\/p>\n

CHANGE\uff0cKobject\uff08\u6216\u4e0b\u5c42\u6570\u636e\u7ed3\u6784\uff09\u7684\u72b6\u6001\u6216\u5219\u5185\u5bb9\u53d1\u751f\u6539\u53d8\u3002<\/p>\n

MOVE\uff0cKobject\uff08\u6216\u4e0b\u5c42\u6570\u636e\u7ed3\u6784\uff09\u66f4\u66f4\u540d\u79f0\u6216\u5219\u4fee\u6539Parent\uff08\u610f\u5473\u7740\u5728sysfs\u4e2d\u4fee\u6539\u4e86\u76ee\u5f55\u7ed3\u6784\uff09\u3002<\/p>\n

CHANGE\uff0c\u5047\u5982\u8bbe\u5907\u9a71\u52a8\u987b\u8981\u4e0a\u62a5\u7684\u98ce\u6ce2\u4e0d\u518d\u524d\u9762\u98ce\u6ce2\u7684\u8303\u56f4\u5185\uff0c\u6216\u5219\u662f\u81ea\u5b9a\u4e49\u7684\u98ce\u6ce2\uff0c\u53ef\u4ee5\u4f7f\u7528\u8be5event\uff0c\u5e76\u643a\u5e26\u76f8\u5e94\u7684\u53c2\u6570\u3002<\/p>\n

\n

 1 \/* include\/linux\/kobject.h, line 31 *\/\n 2: #define UEVENT_NUM_ENVP 32 \/* number of env pointers *\/\n 3: #define UEVENT_BUFFER_SIZE 2048 \/* buffer for the variables *\/\n 4: \n 5: \/* include\/linux\/kobject.h, line 116 *\/\n 6: struct kobj_uevent_env {\n 7: char *envp[UEVENT_NUM_ENVP];\n 8: int envp_idx;\n 9: char buf[UEVENT_BUFFER_SIZE];\n 10: int buflen;\n 11: };\n<\/pre>\n<\/p>\n

linux \u8bbe\u5907\u9a71\u52a8_\u9a71\u52a8\u8bbe\u5907\u65e0\u6cd5\u542f\u52a8\u4ee3\u780110_\u9a71\u52a8\u8bbe\u5907\u6709\u95ee\u9898\u4ee3\u780143<\/p>\n

\u540e\u9762\u6709\u63d0\u53ca\u8fc7\uff0c\u5728\u501f\u52a9Kmod\u5411\u7528\u6237\u7a7a\u95f4\u4e0a\u62a5event\u98ce\u6ce2\u65f6\uff0c\u4f1a\u76f4\u63a5\u6267\u884c\u7528\u6237\u7a7a\u95f4\u7684\u53ef\u6267\u884c\u6587\u4ef6\u3002\u800c\u5728Linux<\/a>\u7cfb\u7edf<\/a>\uff0c\u53ef\u6267\u884c\u6587\u4ef6\u7684\u6267\u884c\uff0c\u4f9d\u8d56\u4e8e\u73af\u5883\u53d8\u91cf\uff0c\u56e0\u800ckobj_uevent_env\u7528\u4e8e\u7ec4\u7ec7\u8fd9\u6b21\u98ce\u6ce2\u4e0a\u62a5\u65f6\u7684\u73af\u5883\u53d8\u91cf\u3002<\/p>\n

envp\uff0c\u8868\u9488\u94fe\u8868\uff0c\u7528\u4e8e\u4fdd\u5b58\u6bcf\u4f4d\u73af\u5883\u53d8\u91cf\u7684\u5730\u5740\uff0c\u6700\u591a\u53ef\u652f\u6301\u7684\u73af\u5883\u53d8\u91cf\u6570\u76ee\u4e3aUEVENT_NUM_ENVP\u3002<\/p>\n

envp_idxlinux\u624b\u673a\u8f6f\u4ef6\uff0c\u7528\u4e8e\u8bbf\u95ee\u73af\u5883\u53d8\u91cf\u8868\u9488\u94fe\u8868\u7684index\u3002<\/p>\n

buf\uff0c\u4fdd\u5b58\u73af\u5883\u53d8\u91cf\u7684buffer\uff0c\u6700\u5927\u4e3aUEVENT_BUFFER_SIZE\u3002<\/p>\n

buflen\uff0c\u8bbf\u95eebuf\u7684\u53d8\u91cf\u3002<\/p>\n

\u9a71\u52a8\u8bbe\u5907\u6709\u95ee\u9898\u4ee3\u780143_linux \u8bbe\u5907\u9a71\u52a8_\u9a71\u52a8\u8bbe\u5907\u65e0\u6cd5\u542f\u52a8\u4ee3\u780110<\/p>\n

\n

 1: \/* include\/linux\/kobject.h, line 123 *\/\n 2: struct kset_uevent_ops {\n 3: int (* const filter)(struct kset *kset, struct kobject *kobj);\n 4: const char *(* const name)(struct kset *kset, struct kobject *kobj);\n 5: int (* const uevent)(struct kset *kset, struct kobject *kobj,\n 6: struct kobj_uevent_env *env);\n 7: };\n<\/pre>\n<\/p>\n

kset_uevent_ops\u662f\u4e3akset\u91cf\u8eab\u8ba2\u505a\u7684\u4e00\u4e2a\u6570\u636e\u7ed3\u6784\uff0c\u4e0a\u9762\u5305\u542bfilter\u548cuevent\u4e24\u4e2a\u53cd\u5f39\u51fd\u6570\uff0c\u597d\u5904\u5982\u4e0b\uff1a<\/p>\n

filter\uff0c\u5f53\u4efb\u4f55Kobject\u987b\u8981\u4e0a\u62a5uevent\u65f6\uff0c\u5b83\u6240\u5c5e\u7684kset\u53ef\u4ee5\u901a\u8fc7\u8be5\u63d2\u53e3\u8fc7\u6ee4\uff0c\u5236\u6b62\u4e0d\u5e0c\u671b\u4e0a\u62a5\u7684event\uff0c\u8fdb\u800c\u8fbe\u5230\u4ece\u6574\u4f53\u4e0a\u7ba1\u7406\u7684\u76ee\u7684\u3002<\/p>\n

name\uff0c\u8be5\u63d2\u53e3\u53ef\u4ee5\u8fd4\u56dekset\u7684\u540d\u79f0\u3002\u5047\u5982\u4e00\u4e2akset\u6ca1\u6709\u5408\u6cd5\u7684\u540d\u79f0\uff0c\u5219\u5176\u4e0b\u7684\u6240\u6709Kobject\u5c06\u4e0d\u5bb9\u8bb8\u4e0a\u62a5uvent.<\/p>\n

uevent\uff0c\u5f53\u4efb\u4f55Kobject\u987b\u8981\u4e0a\u62a5uevent\u65f6\uff0c\u5b83\u6240\u5c5e\u7684kset\u53ef\u4ee5\u901a\u8fc7\u8be5\u63d2\u53e3\u7edf\u4e00\u4e3a\u8fd9\u79cdevent\u6dfb\u52a0\u73af\u5883\u53d8\u91cf\u3002\u7531\u4e8e\u597d\u591a\u65f6\u4faf\u4e0a\u62a5uevent\u65f6\u7684\u73af\u5883\u53d8\u91cf\u90fd\u662f\u76f8\u540c\u7684\uff0c\u56e0\u800c\u53ef\u4ee5\u7531kset\u7edf\u4e00\u5904\u7406\uff0c\u5c31\u4e0d\u987b\u8981\u8ba9\u6bcf\u4f4dKobject\u53ea\u8eab\u6dfb\u52a0\u4e86<\/p>\n

\u9a71\u52a8\u8bbe\u5907\u65e0\u6cd5\u542f\u52a8\u4ee3\u780110_\u9a71\u52a8\u8bbe\u5907\u6709\u95ee\u9898\u4ee3\u780143_linux \u8bbe\u5907\u9a71\u52a8<\/p>\n

3.2\u5185\u90e8\u5b9e\u73b0<\/p>\n

\n

#if defined(CONFIG_HOTPLUG)\nint kobject_uevent(struct kobject *kobj, enum kobject_action action);\nint kobject_uevent_env(struct kobject *kobj, enum kobject_action action,\n char *envp[]);\n__printf(2, 3)\nint add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);\nint kobject_action_type(const char *buf, size_t count,\n enum kobject_action *type);\n \nkobject_uevent_env \uff0c\u4ee5 envp \u4e3a\u73af\u5883\u53d8\u91cf\uff0c\u4e0a\u62a5\u4e00\u4e2a\u6307\u5b9aaction\u7684uevent\u3002\u73af\u5883\u53d8\u91cf\u7684\u4f5c\u7528\u662f\u4e3a\u6267\u884c\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u6307\u5b9a\u8fd0\u884c\u73af\u5883\u3002\nint kobject_uevent(struct kobject *kobj, enum kobject_action action)\n{\n return kobject_uevent_env(kobj, action, NULL);\n}\nint kobject_uevent_env(struct kobject *kobj, enum kobject_action action,\n char *envp_ext[])\n{\n struct kobj_uevent_env *env;\n const char *action_string = kobject_actions[action];\n const char *devpath = NULL;\n const char *subsystem;\n struct kobject *top_kobj;\n struct kset *kset;\n const struct kset_uevent_ops *uevent_ops;\n int i = 0;\n int retval = 0;\n#ifdef CONFIG_NET\n struct uevent_sock *ue_sk;\n#endif\n pr_debug(\"kobject: '%s' (%p): %sn\",\n kobject_name(kobj), kobj, __func__);\n \/* search the kset we belong to *\/\n \/\/1.\u67e5\u627e\u5f53\u524dkobject\u6216\u5176parent\u662f\u5426\u4ece\u5c5e\u4e8e\u67d0\u4e2akset;\u5982\u679c\u90fd\u4e0d\u4ece\u5c5e\u4e8e\u67d0\u4e2akset\uff0c\u5219\u8fd4\u56de\u9519\u8bef\u3002(\u8bf4\u660e\u4e00\u4e2akobject\u82e5\u6ca1\u6709\u52a0\u5165kset\uff0c\u662f\u4e0d\u4f1a\u4e0a\u62a5uevent\u7684)\n top_kobj = kobj;\n while (!top_kobj->kset && top_kobj->parent)\n top_kobj = top_kobj->parent;\n if (!top_kobj->kset) {\n pr_debug(\"kobject: '%s' (%p): %s: attempted to send uevent \"\n \"without kset!n\", kobject_name(kobj), kobj,\n __func__);\n return -EINVAL;\n }\n kset = top_kobj->kset;\n uevent_ops = kset->uevent_ops;\n \/* skip the event, if uevent_suppress is set*\/\n \/\/2.\u67e5\u770bkobj->uevent_suppress\u662f\u5426\u88ab\u8bbe\u7f6e\uff1b\u5982\u679c\u8bbe\u7f6e\u4e86\uff0c\u5219\u5ffd\u7565\u6240\u6709\u7684uevent\u4e0a\u62a5\uff0c\u5e76\u8fd4\u56de0.\n if (kobj->uevent_suppress) {\n pr_debug(\"kobject: '%s' (%p): %s: uevent_suppress \"\n \"caused the event to drop!n\",\n kobject_name(kobj), kobj, __func__);\n return 0;\n }\n \/* skip the event, if the filter returns zero. *\/\n \/\/3.\u5982\u679c\u6240\u5c5e\u7684kset\u6709uevent_ops->filter,\u5219\u8c03\u7528\u8be5\u51fd\u6570\uff0c\u82e5\u8be5\u51fd\u6570\u8fd4\u56de0\uff0c\u5219\u8fc7\u6ee4\u6b64\u6b21\u4e0a\u62a5\u3002(kset \u53ef\u4ee5\u901a\u8fc7filter\u63a5\u53e3\u8fc7\u6ee4\u4e0d\u5e0c\u671b\u4e0a\u62a5\u7684event)\n if (uevent_ops && uevent_ops->filter)\n if (!uevent_ops->filter(kset, kobj)) {\n pr_debug(\"kobject: '%s' (%p): %s: filter function \"\n \"caused the event to drop!n\",\n kobject_name(kobj), kobj, __func__);\n return 0;\n }\n \/* originating subsystem *\/\n \/\/4.\u5224\u65ad\u6240\u5c5e\u7684kset\u662f\u5426\u6709\u5408\u6cd5\u7684\u540d\u79f0,\u82e5uevent_ops->name\u5b58\u5728\u5c31\u7528\u5176\u8fd4\u56de\u7684\u540d\u79f0\u4f5c\u4e3asubsystem;\u82e5uevent_ops->name\u4e0d\u5b58\u5728\u5c31\u7528kset\u672c\u8eab\u7684kobject\u7684\u540d\u79f0\u4f5c\u4e3asubsystem;\n \/\/\u82e5\u6ca1\u6709\u5408\u6cd5\u7684\u540d\u79f0\uff0c\u5219\u4e0d\u4e0a\u62a5uevent\n if (uevent_ops && uevent_ops->name)\n subsystem = uevent_ops->name(kset, kobj);\n else\n subsystem = kobject_name(&kset->kobj);\n if (!subsystem) {\n pr_debug(\"kobject: '%s' (%p): %s: unset subsystem caused the \"\n \"event to drop!n\", kobject_name(kobj), kobj,\n __func__);\n return 0;\n }\n \/* environment buffer *\/\n \/\/5.\u5206\u914d\u4e00\u4e2a\u6b64\u6b21\u4e0a\u62a5\u7684\u7528\u4e8e\u4fdd\u5b58\u73af\u5883\u53d8\u91cf\u7684buffer,\n env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);\n if (!env)\n return -ENOMEM;\n \/* complete object path *\/\n \/\/6.\u83b7\u5f97\u8be5kobject\u5728sysfs\u4e2d\u8def\u5f84\n devpath = kobject_get_path(kobj, GFP_KERNEL);\n if (!devpath) {\n retval = -ENOENT;\n goto exit;\n }\n \/* default keys *\/\n \/\/7.\u6dfb\u52a0ACTION\u5230env\n retval = add_uevent_var(env, \"ACTION=%s\", action_string);\n if (retval)\n goto exit;\n \/\/8.\u6dfb\u52a0DEVPATH(kobject\u8def\u5f84\u4fe1\u606f)\u5230env\n retval = add_uevent_var(env, \"DEVPATH=%s\", devpath);\n if (retval)\n goto exit;\n \/\/9.\u6dfb\u52a0SUBSYSTEM\u5230env\n retval = add_uevent_var(env, \"SUBSYSTEM=%s\", subsystem);\n if (retval)\n goto exit;\n \/* keys passed in from the caller *\/\n \/\/10.\u5982\u679c\u4f20\u5165\u7684envp_ext\u4e0d\u7a7a\uff0c\u5219\u89e3\u6790\u4f20\u5165\u7684\u73af\u5883\u53d8\u91cf\u4e2d\uff0c\u540c\u6837\u8c03\u7528add_uevent_var\u63a5\u53e3\uff0c\u6dfb\u52a0\u5230env\u6307\u9488\u4e2d\n if (envp_ext) {\n for (i = 0; envp_ext[i]; i++) {\n retval = add_uevent_var(env, \"%s\", envp_ext[i]);\n if (retval)\n goto exit;\n }\n }\n \/* let the kset specific function add its stuff *\/\n \/\/11.\u5982\u679c uevent_ops->uevent \u5b58\u5728\uff0c\u8c03\u7528\u8be5\u63a5\u53e3\uff0c\u6dfb\u52a0kset\u7edf\u4e00\u7684\u73af\u5883\u53d8\u91cf\u5230env\u6307\u9488\n if (uevent_ops && uevent_ops->uevent) {\n retval = uevent_ops->uevent(kset, kobj, env);\n if (retval) {\n pr_debug(\"kobject: '%s' (%p): %s: uevent() returned \"\n \"%dn\", kobject_name(kobj), kobj,\n __func__, retval);\n goto exit;\n }\n }\n \/*\n * Mark \"add\" and \"remove\" events in the object to ensure proper\n * events to userspace during automatic cleanup. If the object did\n * send an \"add\" event, \"remove\" will automatically generated by\n * the core, if not already done by the caller.\n *\/\n \/\/12.\u6839\u636eACTION\u7684\u7c7b\u578b\uff0c\u8bbe\u7f6ekobj->state_add_uevent_sent\u548ckobj->state_remove_uevent_sent\u53d8\u91cf\uff0c\u4ee5\u8bb0\u5f55\u6b63\u786e\u7684\u72b6\u6001\n if (action == KOBJ_ADD)\n kobj->state_add_uevent_sent = 1;\n else if (action == KOBJ_REMOVE)\n kobj->state_remove_uevent_sent = 1;\n mutex_lock(&uevent_sock_mutex);\n \/* we will send an event, so request a new sequence number *\/\n \/\/13.\u8c03\u7528add_uevent_var\u63a5\u53e3\uff0c\u6dfb\u52a0\u683c\u5f0f\u4e3a\"SEQNUM=%llu\u201d\u7684\u5e8f\u5217\u53f7\n retval = add_uevent_var(env, \"SEQNUM=%llu\", (unsigned long long)++uevent_seqnum);\n if (retval) {\n mutex_unlock(&uevent_sock_mutex);\n goto exit;\n }\n\/\/14.\u5982\u679c\u5b9a\u4e49\u4e86\"CONFIG_NET\u201d\uff0c\u5219\u4f7f\u7528netlink\u53d1\u9001\u8be5uevent\n#if defined(CONFIG_NET)\n \/* send netlink message *\/\n list_for_each_entry(ue_sk, &uevent_sock_list, list) {\n struct sock *uevent_sock = ue_sk->sk;\n struct sk_buff *skb;\n size_t len;\n if (!netlink_has_listeners(uevent_sock, 1))\n continue;\n \/* allocate message with the maximum possible size *\/\n len = strlen(action_string) + strlen(devpath) + 2;\n skb = alloc_skb(len + env->buflen, GFP_KERNEL);\n if (skb) {\n char *scratch;\n \/* add header *\/\n scratch = skb_put(skb, len);\n sprintf(scratch, \"%s@%s\", action_string, devpath);\n \/* copy keys to our continuous event payload buffer *\/\n for (i = 0; i envp_idx; i++) {\n len = strlen(env->envp[i]) + 1;\n scratch = skb_put(skb, len);\n strcpy(scratch, env->envp[i]);\n }\n NETLINK_CB(skb).dst_group = 1;\n retval = netlink_broadcast_filtered(uevent_sock, skb,\n 0, 1, GFP_KERNEL,\n kobj_bcast_filter,\n kobj);\n \/* ENOBUFS should be handled in userspace *\/\n if (retval == -ENOBUFS || retval == -ESRCH)\n retval = 0;\n } else\n retval = -ENOMEM;\n }\n#endif\n mutex_unlock(&uevent_sock_mutex);\n \/* call uevent_helper, usually only enabled during early boot *\/\n \/\/15.\u4ee5uevent_helper\u3001 subsystem \u4ee5\u53ca\u6dfb\u52a0\u4e86\u6807\u51c6\u73af\u5883\u53d8\u91cf\uff08HOME=\/\uff0cPATH=\/sbin:\/bin:\/usr\/sbin:\/usr\/bin\uff09\u7684env\u6307\u9488\u4e3a\u53c2\u6570\uff0c\n \/\/ \u8c03\u7528kmod\u6a21\u5757\u63d0\u4f9b\u7684call_usermodehelper\u51fd\u6570\uff0c\u4e0a\u62a5uevent\u3002\n if (uevent_helper[0] && !kobj_usermode_filter(kobj)) {\n char *argv [3];\n argv [0] = uevent_helper;\/\/\u5728\/sys\/kernel\/uevent_helper\u6587\u4ef6\u4e2d\u53ef\u4ee5\u5b58\u5165\u7528\u6237\u7a7a\u95f4\u53ef\u6267\u884c\u7a0b\u5e8f\u7684\u8def\u5f84\uff0c\u5f53\u5185\u6838\u6709\u4e8b\u4ef6\u53d1\u751f\u65f6\uff0c\u5c06\u4f1a\u6267\u884c\u8be5\u7a0b\u5e8f\n argv [1] = (char *)subsystem;\n argv [2] = NULL;\n retval = add_uevent_var(env, \"HOME=\/\");\n if (retval)\n goto exit;\n retval = add_uevent_var(env,\n \"PATH=\/sbin:\/bin:\/usr\/sbin:\/usr\/bin\");\n if (retval)\n goto exit;\n retval = call_usermodehelper(argv[0], argv,\n env->envp, UMH_WAIT_EXEC);\n }\nexit:\n kfree(devpath);\n kfree(env);\n return retval;\n}\n<\/pre>\n<\/p>\n

uevent\u6a21\u5757\u901a\u8fc7kmod\u4e0a\u62a5uevent\u65f6\uff0c\u4f1a\u901a\u8fc7call_usermodehelper\u51fd\u6570\uff0c\u8c03\u7528\u7528\u6237\u7a7a\u95f4\u7684\u53ef\u6267\u884c\u6587\u4ef6\uff08\u6216\u5219\u811a\u672c\uff0c\u7b80\u79f0ueventhelper\uff09\u5904\u7406\u8be5event\u3002\u800c\u8be5ueventhelper\u7684\u8def\u5f84\u4fdd\u5b58\u5728uevent_helper\u5b57\u6bb5\u4e2d\u3002<\/p>\n

\u53ef\u4ee5\u5728\u7f16\u8bd1\u5185\u6838\u65f6\uff0c\u901a\u8fc7CONFIG_UEVENT_HELPER_PATH\u914d\u7f6e\u9879\uff0c\u9759\u6001\u6307\u5b9aueventhelper\u3002\u4f46\u8fd9\u4e9b\u65b9\u6cd5\u4f1a\u4e3a\u6bcf\u4f4deventfork\u4e00\u4e2a\u8fdb\u7a0b\uff0c\u968f\u7740\u5185\u6838\u652f\u6301\u7684\u8bbe\u5907\u6570\u76ee\u7684\u589e\u591a\uff0c\u8fd9\u4e9b\u65b9\u6cd5\u5728\u7cfb\u7edf\u542f\u52a8\u65f6\u5c06\u4f1a\u662f\u81f4\u547d\u7684\uff08\u53ef\u4ee5\u9020\u6210\u663e\u5b58\u6ea2\u51fa\u7b49\uff09\u3002\u56e0\u800c\u53ea\u6709\u5728\u521d\u671f\u7684\u5185\u6838\u7248\u672c\u4e2d\u4f1a\u4f7f\u7528\u8fd9\u4e9b\u65b9\u6cd5\uff0c\u5982\u4eca\u5185\u6838\u4e0d\u518d\u63a8\u8350\u4f7f\u7528\u8be5\u65b9\u6cd5\u3002\u56e0\u800c\u5185\u6838\u7f16\u8bd1\u65f6\uff0c\u987b\u8981\u628a\u8be5\u914d\u7f6e\u9879\u7559\u7a7a\u3002<\/p>\n

\u5728\u7cfb\u7edf\u542f\u52a8\u540e\uff0c\u5927\u90e8\u4efd\u7684\u8bbe\u5907\u5df2\u7136ready\uff0c\u53ef\u4ee5\u6309\u7167\u987b\u8981linux \u8bbe\u5907\u9a71\u52a8<\/strong>\uff0c\u91cd\u65b0\u6307\u5b9a\u4e00\u4e2aueventhelper\uff0c\u4fbf\u4e8e\u6d4b\u91cf\u7cfb\u7edf\u8fd0\u884c\u8fc7\u7a0b\u4e2d\u7684\u70ed\u63d2\u62d4\u98ce\u6ce2\u3002\u8fd9\u53ef\u4ee5\u901a\u8fc7\u628ahelper\u7684\u8def\u5f84\u5199\u5165\u5230\"\/sys\/kernel\/uevent_helper\"\u6587\u4ef6\u4e2d\u5b9e\u73b0\u3002\u5b9e\u9645\u4e0a\uff0c\u5185\u6838\u901a\u8fc7sysfs\u6587\u4ef6\u7cfb\u7edf\u7684\u65b9\u5f0f\uff0c\u5c06uevent_helper\u94fe\u8868\u5f00\u653e\u5230\u7528\u6237\u7a7a\u95f4\uff0c\u4f9b\u7528\u6237\u7a7a\u95f4\u7a0b\u5e8f\u66f4\u6539\u8bbf\u95ee\uff0c\u5177\u4f53\u53ef\u53c2\u8003\".\/kernel\/ksysfs.c\u201d\u4e2d\u76f8\u5e94\u7684\u4ee3\u7801\u3002<\/p>\n

\u5728\/etc\/init.d\/rcS\u811a\u672c\u4e2d\u6dfb\u52a0echo\"\/sbin\/mdev\">\/proc\/sys\/kernel\/hotplug\uff0c\u4f1a\u53d1\u89c9cat\/sys\/kernel\/uevent_helper\u5373\u662f\/sbin\/mdev\u3002\u8bf4\u660e\/proc\/sys\/kernel\/hotplug\u4e2d\u7684\u53ef\u6267\u884c\u6587\u4ef6\u8def\u5f84\u6700\u7ec8\u8fd8\u662f\u4f1a\u8bb2\u5230\/sys\/kernel\/uevent_helper\u4e2d\u3002<\/p>\n

\u81ea\u5df1\u81ea\u52a8echo\"\/kernel\/main\">uevent_helper(\u4e4b\u524d\u7684\/sbin\/mdev\u4f1a\u88ab\u8986\u76d6)\u7ea2\u5e3dlinux\uff0c\u5f53lsmod\u3001rmmod\u65f6\uff0c\/sys\/kernel\/uevent_helper\u4e2d\u7684\/kernel\/main\u4f1a\u6267\u884c\uff0c\u8868\u660e\u98ce\u6ce2\u65e9\u5df2\u4e0a\u62a5\u7ed9\u7528\u6237\u7a7a\u95f4\u3002<\/p>\n

call_usermodehelper\u51fd\u6570\u5c31\u80fd\u4fbf\u6377\u7684\u5728\u5185\u6838\u4e2d\u76f4\u63a5\u65b0\u5efa\u548c\u8fd0\u884c\u7528\u6237\u7a7a\u95f4\u7684\u7a0b\u5e8f\uff0c\u4f46\u662f\u8be5\u7a0b\u5e8f\u6709root\u6743\u9650\u3002call_usermodeheler\u51fd\u6570\u7684\u53c2\u6570\u7528\u6cd5\u548cexecve\u51fd\u6570\u4e00\u81f4\u3002call_usermodehelper()->call_usermodehelper_exec()<\/p>\n","protected":false},"excerpt":{"rendered":"

CHANGE\uff0c\u5982\u679c\u8bbe\u5907\u9a71\u52a8\u9700\u8981\u4e0a\u62a5\u7684\u4e8b\u4ef6\u4e0d\u518d\u4e0a\u9762\u4e8b\u4ef6\u7684\u8303\u56f4\u5185\uff0c\u6216\u8005\u662f\u81ea\u5b9a\u4e49\u7684\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u4f7f\u7528\u8be5event\uff0c\u5e76\u643a\u5e26\u76f8\u5e94\u7684\u53c2\u6570\u3002call_usermodehelper\u51fd\u6570\u80fd\u591f\u65b9\u4fbf\u7684\u5728\u5185\u6838\u4e2d\u76f4\u63a5\u65b0\u5efa\u548c\u8fd0\u884c\u7528\u6237\u7a7a\u95f4\u7684\u7a0b\u5e8f\uff0c\u5e76\u4e14\u8be5\u7a0b\u5e8f\u6709root\u6743\u9650\u3002<\/p>\n","protected":false},"author":1,"featured_media":292693,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[988],"tags":[999],"class_list":["post-292692","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tougao","tag-999"],"acf":[],"_links":{"self":[{"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/posts\/292692","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/comments?post=292692"}],"version-history":[{"count":0,"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/posts\/292692\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/media\/292693"}],"wp:attachment":[{"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/media?parent=292692"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/categories?post=292692"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lrxjmw.cn\/wp-json\/wp\/v2\/tags?post=292692"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}