Advertisement
neochapay

Untitled

Sep 29th, 2016
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.99 KB | None | 0 0
  1. /*
  2.  * devtmpfs - kernel-maintained tmpfs-based /dev
  3.  *
  4.  * Copyright (C) 2009, Kay Sievers <kay.sievers@vrfy.org>
  5.  *
  6.  * During bootup, before any driver core device is registered,
  7.  * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
  8.  * device which requests a device node, will add a node in this
  9.  * filesystem.
  10.  * By default, all devices are named after the name of the device,
  11.  * owned by root and have a default mode of 0600. Subsystems can
  12.  * overwrite the default setting if needed.
  13.  */
  14.  
  15. #include <linux/kernel.h>
  16. #include <linux/syscalls.h>
  17. #include <linux/mount.h>
  18. #include <linux/device.h>
  19. #include <linux/genhd.h>
  20. #include <linux/namei.h>
  21. #include <linux/fs.h>
  22. #include <linux/shmem_fs.h>
  23. #include <linux/ramfs.h>
  24. #include <linux/sched.h>
  25. #include <linux/slab.h>
  26. #include <linux/kthread.h>
  27. #include "base.h"
  28.  
  29. static struct task_struct *thread;
  30.  
  31. #if defined CONFIG_DEVTMPFS_MOUNT
  32. static int mount_dev = 1;
  33. #else
  34. static int mount_dev;
  35. #endif
  36.  
  37. static DEFINE_SPINLOCK(req_lock);
  38.  
  39. static struct req {
  40.         struct req *next;
  41.         struct completion done;
  42.         int err;
  43.         const char *name;
  44.         umode_t mode;   /* 0 => delete */
  45.         kuid_t uid;
  46.         kgid_t gid;
  47.         struct device *dev;
  48. } *requests;
  49.  
  50. static int __init mount_param(char *str)
  51. {
  52.         mount_dev = simple_strtoul(str, NULL, 0);
  53.         return 1;
  54. }
  55. __setup("devtmpfs.mount=", mount_param);
  56.  
  57. static struct dentry *dev_mount(struct file_system_type *fs_type, int flags,
  58.                       const char *dev_name, void *data)
  59. {
  60. #ifdef CONFIG_TMPFS
  61.         return mount_single(fs_type, flags, data, shmem_fill_super);
  62. #else
  63.         return mount_single(fs_type, flags, data, ramfs_fill_super);
  64. #endif
  65. }
  66.  
  67. static struct file_system_type dev_fs_type = {
  68.         .name = "devtmpfs",
  69.         .mount = dev_mount,
  70.         .kill_sb = kill_litter_super,
  71. };
  72.  
  73. #ifdef CONFIG_BLOCK
  74. static inline int is_blockdev(struct device *dev)
  75. {
  76.         return dev->class == &block_class;
  77. }
  78. #else
  79. static inline int is_blockdev(struct device *dev) { return 0; }
  80. #endif
  81.  
  82. int devtmpfs_create_node(struct device *dev)
  83. {
  84.         const char *tmp = NULL;
  85.         struct req req;
  86.  
  87.         if (!thread)
  88.                 return 0;
  89.  
  90.         req.mode = 0;
  91.         req.uid = GLOBAL_ROOT_UID;
  92.         req.gid = GLOBAL_ROOT_GID;
  93.         req.name = device_get_devnode(dev, &req.mode, &req.uid, &req.gid, &tmp);
  94.         if (!req.name)
  95.                 return -ENOMEM;
  96.  
  97.         if (req.mode == 0)
  98.                 req.mode = 0600;
  99.         if (is_blockdev(dev))
  100.                 req.mode |= S_IFBLK;
  101.         else
  102.                 req.mode |= S_IFCHR;
  103.  
  104.         req.dev = dev;
  105.  
  106.         init_completion(&req.done);
  107.  
  108.         spin_lock(&req_lock);
  109.         req.next = requests;
  110.         requests = &req;
  111.         spin_unlock(&req_lock);
  112.  
  113.         wake_up_process(thread);
  114.         wait_for_completion(&req.done);
  115.  
  116.         kfree(tmp);
  117.  
  118.         return req.err;
  119. }
  120.  
  121. int devtmpfs_delete_node(struct device *dev)
  122. {
  123.         const char *tmp = NULL;
  124.         struct req req;
  125.  
  126.         if (!thread)
  127.                 return 0;
  128.  
  129.         req.name = device_get_devnode(dev, NULL, NULL, NULL, &tmp);
  130.         if (!req.name)
  131.                 return -ENOMEM;
  132.  
  133.         req.mode = 0;
  134.         req.dev = dev;
  135.  
  136.         init_completion(&req.done);
  137.  
  138.         spin_lock(&req_lock);
  139.         req.next = requests;
  140.         requests = &req;
  141.         spin_unlock(&req_lock);
  142.  
  143.         wake_up_process(thread);
  144.         wait_for_completion(&req.done);
  145.  
  146.         kfree(tmp);
  147.         return req.err;
  148. }
  149.  
  150. static int dev_mkdir(const char *name, umode_t mode)
  151. {
  152.         struct dentry *dentry;
  153.         struct path path;
  154.         int err;
  155.  
  156.         dentry = kern_path_create(AT_FDCWD, name, &path, LOOKUP_DIRECTORY);
  157.         if (IS_ERR(dentry))
  158.                 return PTR_ERR(dentry);
  159.  
  160.         err = vfs_mkdir(path.dentry->d_inode, dentry, mode);
  161.         if (!err)
  162.                 /* mark as kernel-created inode */
  163.                 dentry->d_inode->i_private = &thread;
  164.         done_path_create(&path, dentry);
  165.         return err;
  166. }
  167.  
  168. static int create_path(const char *nodepath)
  169. {
  170.         char *path;
  171.         char *s;
  172.         int err = 0;
  173.  
  174.         /* parent directories do not exist, create them */
  175.         path = kstrdup(nodepath, GFP_KERNEL);
  176.         if (!path)
  177.                 return -ENOMEM;
  178.  
  179.         s = path;
  180.         for (;;) {
  181.                 s = strchr(s, '/');
  182.                 if (!s)
  183.                         break;
  184.                 s[0] = '\0';
  185.                 err = dev_mkdir(path, 0755);
  186.                 if (err && err != -EEXIST)
  187.                         break;
  188.                 s[0] = '/';
  189.                 s++;
  190.         }
  191.         kfree(path);
  192.         return err;
  193. }
  194.  
  195. static int handle_create(const char *nodename, umode_t mode, kuid_t uid,
  196.                          kgid_t gid, struct device *dev)
  197. {
  198.         struct dentry *dentry;
  199.         struct path path;
  200.         int err;
  201.  
  202.         dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
  203.         if (dentry == ERR_PTR(-ENOENT)) {
  204.                 create_path(nodename);
  205.                 dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
  206.         }
  207.         if (IS_ERR(dentry))
  208.                 return PTR_ERR(dentry);
  209.  
  210.         err = vfs_mknod(path.dentry->d_inode, dentry, mode, dev->devt);
  211.         if (!err) {
  212.                 struct iattr newattrs;
  213.  
  214.                 newattrs.ia_mode = mode;
  215.                 newattrs.ia_uid = uid;
  216.                 newattrs.ia_gid = gid;
  217.                 newattrs.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID;
  218.                 mutex_lock(&dentry->d_inode->i_mutex);
  219.                 notify_change(dentry, &newattrs);
  220.                 mutex_unlock(&dentry->d_inode->i_mutex);
  221.  
  222.                 /* mark as kernel-created inode */
  223.                 dentry->d_inode->i_private = &thread;
  224.         }
  225.         done_path_create(&path, dentry);
  226.         return err;
  227. }
  228.  
  229. static int dev_rmdir(const char *name)
  230. {
  231.         struct path parent;
  232.         struct dentry *dentry;
  233.         int err;
  234.  
  235.         dentry = kern_path_locked(name, &parent);
  236.         if (IS_ERR(dentry))
  237.                 return PTR_ERR(dentry);
  238.         if (dentry->d_inode) {
  239.                 if (dentry->d_inode->i_private == &thread)
  240.                         err = vfs_rmdir(parent.dentry->d_inode, dentry);
  241.                 else
  242.                         err = -EPERM;
  243.         } else {
  244.                 err = -ENOENT;
  245.         }
  246.         dput(dentry);
  247.         mutex_unlock(&parent.dentry->d_inode->i_mutex);
  248.         path_put(&parent);
  249.         return err;
  250. }
  251.  
  252. static int delete_path(const char *nodepath)
  253. {
  254.         const char *path;
  255.         int err = 0;
  256.  
  257.         path = kstrdup(nodepath, GFP_KERNEL);
  258.         if (!path)
  259.                 return -ENOMEM;
  260.  
  261.         for (;;) {
  262.                 char *base;
  263.  
  264.                 base = strrchr(path, '/');
  265.                 if (!base)
  266.                         break;
  267.                 base[0] = '\0';
  268.                 err = dev_rmdir(path);
  269.                 if (err)
  270.                         break;
  271.         }
  272.  
  273.         kfree(path);
  274.         return err;
  275. }
  276.  
  277. static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat)
  278. {
  279.         /* did we create it */
  280.         if (inode->i_private != &thread)
  281.                 return 0;
  282.  
  283.         /* does the dev_t match */
  284.         if (is_blockdev(dev)) {
  285.                 if (!S_ISBLK(stat->mode))
  286.                         return 0;
  287.         } else {
  288.                 if (!S_ISCHR(stat->mode))
  289.                         return 0;
  290.         }
  291.         if (stat->rdev != dev->devt)
  292.                 return 0;
  293.  
  294.         /* ours */
  295.         return 1;
  296. }
  297.  
  298. static int handle_remove(const char *nodename, struct device *dev)
  299. {
  300.         struct path parent;
  301.         struct dentry *dentry;
  302.         int deleted = 1;
  303.         int err;
  304.  
  305.         dentry = kern_path_locked(nodename, &parent);
  306.         if (IS_ERR(dentry))
  307.                 return PTR_ERR(dentry);
  308.  
  309.         if (dentry->d_inode) {
  310.                 struct kstat stat;
  311.                 struct path p = {.mnt = parent.mnt, .dentry = dentry};
  312.                 err = vfs_getattr(&p, &stat);
  313.                 if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
  314.                         struct iattr newattrs;
  315.                         /*
  316.                          * before unlinking this node, reset permissions
  317.                          * of possible references like hardlinks
  318.                          */
  319.                         newattrs.ia_uid = GLOBAL_ROOT_UID;
  320.                         newattrs.ia_gid = GLOBAL_ROOT_GID;
  321.                         newattrs.ia_mode = stat.mode & ~0777;
  322.                         newattrs.ia_valid =
  323.                                 ATTR_UID|ATTR_GID|ATTR_MODE;
  324.                         mutex_lock(&dentry->d_inode->i_mutex);
  325.                         notify_change(dentry, &newattrs);
  326.                         mutex_unlock(&dentry->d_inode->i_mutex);
  327.                         err = vfs_unlink(parent.dentry->d_inode, dentry);
  328.                         if (!err || err == -ENOENT)
  329.                                 deleted = 1;
  330.                 }
  331.         } else {
  332.                 err = -ENOENT;
  333.         }
  334.         dput(dentry);
  335.         mutex_unlock(&parent.dentry->d_inode->i_mutex);
  336.  
  337.         path_put(&parent);
  338.         if (deleted && strchr(nodename, '/'))
  339.                 delete_path(nodename);
  340.         return err;
  341. }
  342.  
  343. /*
  344.  * If configured, or requested by the commandline, devtmpfs will be
  345.  * auto-mounted after the kernel mounted the root filesystem.
  346.  */
  347. int devtmpfs_mount(const char *mntdir)
  348. {
  349.         int err;
  350.  
  351.         if (!mount_dev)
  352.                 return 0;
  353.  
  354.         if (!thread)
  355.                 return 0;
  356.  
  357.         err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL);
  358.         if (err)
  359.                 printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
  360.         else
  361.                 printk(KERN_INFO "devtmpfs: mounted\n");
  362.         return err;
  363. }
  364.  
  365. static DECLARE_COMPLETION(setup_done);
  366.  
  367. static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
  368.                   struct device *dev)
  369. {
  370.         if (mode)
  371.                 return handle_create(name, mode, uid, gid, dev);
  372.         else
  373.                 return handle_remove(name, dev);
  374. }
  375.  
  376. static int devtmpfsd(void *p)
  377. {
  378. //      char options[] = "mode=0755";
  379.         char *options;
  380.         int *err = p;
  381.         *err = sys_unshare(CLONE_NEWNS);
  382.                 goto out;
  383.         /*
  384.         * The options argument has to be PAGE_SIZE bytes of initialized memory
  385.         * region, or kmemcheck will complain "read from uninitialized memory"
  386.         * because copy_mount_options() tries to copy PAGE_SIZE bytes.
  387.         */
  388.         options = (char *) __get_free_page(GFP_KERNEL | __GFP_ZERO);
  389.         if (!options) {
  390.             *err = -ENOMEM;
  391.             goto out;
  392.         }
  393.         strcpy(options, "mode=0755");
  394.  
  395.         *err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options);
  396.         free_page((unsigned long) options);
  397.  
  398.         //*err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options);
  399.         if (*err)
  400.                 goto out;
  401.         sys_chdir("/.."); /* will traverse into overmounted root */
  402.         sys_chroot(".");
  403.         complete(&setup_done);
  404.         while (1) {
  405.                 spin_lock(&req_lock);
  406.                 while (requests) {
  407.                         struct req *req = requests;
  408.                         requests = NULL;
  409.                         spin_unlock(&req_lock);
  410.                         while (req) {
  411.                                 struct req *next = req->next;
  412.                                 req->err = handle(req->name, req->mode,
  413.                                                   req->uid, req->gid, req->dev);
  414.                                 complete(&req->done);
  415.                                 req = next;
  416.                         }
  417.                         spin_lock(&req_lock);
  418.                 }
  419.                 __set_current_state(TASK_INTERRUPTIBLE);
  420.                 spin_unlock(&req_lock);
  421.                 schedule();
  422.         }
  423.         return 0;
  424. out:
  425.         complete(&setup_done);
  426.         return *err;
  427. }
  428.  
  429. /*
  430.  * Create devtmpfs instance, driver-core devices will add their device
  431.  * nodes here.
  432.  */
  433. int __init devtmpfs_init(void)
  434. {
  435.         int err = register_filesystem(&dev_fs_type);
  436.         if (err) {
  437.                 printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
  438.                        "type %i\n", err);
  439.                 return err;
  440.         }
  441.  
  442.         thread = kthread_run(devtmpfsd, &err, "kdevtmpfs");
  443.         if (!IS_ERR(thread)) {
  444.                 wait_for_completion(&setup_done);
  445.         } else {
  446.                 err = PTR_ERR(thread);
  447.                 thread = NULL;
  448.         }
  449.  
  450.         if (err) {
  451.                 printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
  452.                 unregister_filesystem(&dev_fs_type);
  453.                 return err;
  454.         }
  455.  
  456.         printk(KERN_INFO "devtmpfs: initialized\n");
  457.         return 0;
  458. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement