On Sun, Dec 11, 2005 at 04:47:26PM -0500, Raul Miller wrote:
> Here's what I currently see suggested:
> 1) change devmapper defaults -- patch rejected, no reason given
> 2) explicitly use udev -- problem, this doesn't work for 2.4 kernels
> (2.4 used devfs)
> 3) avoid using devmapper (but this is not a solution)
4) the two attached patches:
   - devmapper: export functions to set permissions
   - lvm2: add a config entry to overwrite the permissions for new
     devices

I just try to get it acked by upstream and search for some other people
to test them, if this solution is acceptable.

Bastian

-- 
A Vulcan can no sooner be disloyal than he can exist without breathing.
                -- Kirk, "The Menagerie", stardate 3012.4
=== debian/changelog
==================================================================
--- debian/changelog    (revision 206)
+++ debian/changelog    (local)
@@ -1,3 +1,9 @@
+devmapper (2:1.02.02-1.0permission.1) UNRELEASED; urgency=low
+
+  * Make device mode modificable.
+
+ -- Bastian Blank <[EMAIL PROTECTED]>  Fri, 23 Dec 2005 20:03:04 +0100
+
 devmapper (2:1.02.02-1) unstable; urgency=low
 
   * New upstram version. 
=== debian/rules
==================================================================
--- debian/rules        (revision 206)
+++ debian/rules        (local)
@@ -117,7 +117,7 @@
        dh_link -a
        dh_compress -a
        dh_fixperms -a
-       dh_makeshlibs -a
+       dh_makeshlibs -a -V 'libdevmapper1.02 (>= 2:1.02.02-1.0permission.1)'
        dh_installdeb -a
        dh_shlibdeps -a
        dh_gencontrol -a
=== dmsetup/dmsetup.c
==================================================================
--- dmsetup/dmsetup.c   (revision 206)
+++ dmsetup/dmsetup.c   (local)
@@ -88,6 +88,9 @@
        EXEC_ARG,
        MAJOR_ARG,
        MINOR_ARG,
+       UID_ARG,
+       GID_ARG,
+       MODE_ARG,
        NOHEADINGS_ARG,
        NOLOCKFS_ARG,
        NOOPENCOUNT_ARG,
@@ -390,6 +393,15 @@
        if (_switches[MINOR_ARG] && !dm_task_set_minor(dmt, _values[MINOR_ARG]))
                goto out;
 
+       if (_switches[UID_ARG] && !_dm_task_set_uid(dmt, _values[UID_ARG]))
+               goto out;
+
+       if (_switches[GID_ARG] && !_dm_task_set_gid(dmt, _values[GID_ARG]))
+               goto out;
+
+       if (_switches[MODE_ARG] && !_dm_task_set_mode(dmt, _values[MODE_ARG]))
+               goto out;
+
        if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
                goto out;
 
@@ -1292,7 +1304,8 @@
 
 static struct command _commands[] = {
        {"create", "<dev_name> [-j|--major <major> -m|--minor <minor>]\n"
-         "\t                  [-u|uuid <uuid>] [--notable] [<table_file>]",
+         "\t                  [-u|uuid <uuid>] [-U|--uid <uid>] [-G|--gid 
<gid>]\n"
+         "\t                  [-M|--mode <mode>] [--notable] [<table_file>]",
         1, 2, _create},
        {"remove", "<device>", 0, 1, _remove},
        {"remove_all", "", 0, 0, _remove_all},
@@ -1420,6 +1433,9 @@
                {"exec", 1, &ind, EXEC_ARG},
                {"major", 1, &ind, MAJOR_ARG},
                {"minor", 1, &ind, MINOR_ARG},
+               {"uid", 1, &ind, UID_ARG},
+               {"gid", 1, &ind, GID_ARG},
+               {"mode", 1, &ind, MODE_ARG},
                {"noheadings", 0, &ind, NOHEADINGS_ARG},
                {"nolockfs", 0, &ind, NOLOCKFS_ARG},
                {"noopencount", 0, &ind, NOOPENCOUNT_ARG},
@@ -1478,10 +1494,14 @@
 
        optarg = 0;
        optind = OPTIND_INIT;
-       while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCj:m:no:ru:v",
+       while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCj:G:m:M:no:ru:U:v",
                                            long_options, NULL)) != -1) {
                if (c == 'c' || c == 'C' || ind == COLS_ARG)
                        _switches[COLS_ARG]++;
+               if (c == 'G' || ind == GID_ARG) {
+                       _switches[GID_ARG]++;
+                       _values[GID_ARG] = strtol(optarg, NULL, 10);
+               }
                if (c == 'r' || ind == READ_ONLY)
                        _switches[READ_ONLY]++;
                if (c == 'j' || ind == MAJOR_ARG) {
@@ -1492,6 +1512,10 @@
                        _switches[MINOR_ARG]++;
                        _values[MINOR_ARG] = atoi(optarg);
                }
+               if (c == 'M' || ind == MODE_ARG) {
+                       _switches[MODE_ARG]++;
+                       _values[MODE_ARG] = strtol(optarg, NULL, 8);
+               }
                if (c == 'n' || ind == NOTABLE_ARG)
                        _switches[NOTABLE_ARG]++;
                if (c == 'o' || ind == OPTIONS_ARG) {
@@ -1504,6 +1528,10 @@
                        _switches[UUID_ARG]++;
                        _uuid = optarg;
                }
+               if (c == 'U' || ind == UID_ARG) {
+                       _switches[UID_ARG]++;
+                       _values[UID_ARG] = strtol(optarg, NULL, 10);
+               }
                if ((ind == EXEC_ARG)) {
                        _switches[EXEC_ARG]++;
                        _command = optarg;
=== lib/.exported_symbols
==================================================================
--- lib/.exported_symbols       (revision 206)
+++ lib/.exported_symbols       (local)
@@ -20,6 +20,9 @@
 dm_task_set_event_nr
 dm_task_set_major
 dm_task_set_minor
+_dm_task_set_uid
+_dm_task_set_gid
+_dm_task_set_mode
 dm_task_set_sector
 dm_task_set_message
 dm_task_suppress_identical_reload
@@ -36,6 +39,7 @@
 dm_tree_free
 dm_tree_add_dev
 dm_tree_add_new_dev
+_dm_tree_add_new_dev_mode
 dm_tree_node_get_name
 dm_tree_node_get_uuid
 dm_tree_node_get_info
=== lib/ioctl/libdm-iface.c
==================================================================
--- lib/ioctl/libdm-iface.c     (revision 206)
+++ lib/ioctl/libdm-iface.c     (local)
@@ -1310,6 +1310,9 @@
 
        task->major = dmt->major;
        task->minor = dmt->minor;
+       task->uid = dmt->uid;
+       task->gid = dmt->gid;
+       task->mode = dmt->mode;
 
        r = dm_task_run(task);
        dm_task_destroy(task);
=== lib/libdevmapper.h
==================================================================
--- lib/libdevmapper.h  (revision 206)
+++ lib/libdevmapper.h  (local)
@@ -143,6 +143,9 @@
 int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
 int dm_task_set_message(struct dm_task *dmt, const char *message);
 int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
+int _dm_task_set_uid(struct dm_task *dmt, uid_t uid);
+int _dm_task_set_gid(struct dm_task *dmt, gid_t gid);
+int _dm_task_set_mode(struct dm_task *dmt, mode_t mode);
 int dm_task_no_open_count(struct dm_task *dmt);
 int dm_task_skip_lockfs(struct dm_task *dmt);
 int dm_task_suppress_identical_reload(struct dm_task *dmt);
@@ -234,6 +237,15 @@
                                             int clear_inactive,
                                             void *context);
 
+struct dm_tree_node *_dm_tree_add_new_dev_mode(struct dm_tree *tree,
+                                            const char *name,
+                                            const char *uuid,
+                                            uint32_t major, uint32_t minor,
+                                            uid_t uid, uid_t gid, mode_t mode,
+                                            int read_only,
+                                            int clear_inactive,
+                                            void *context);
+
 /*
  * Search for a node in the tree.
  * Set major and minor to 0 or uuid to NULL to get the root node.
=== lib/libdm-common.c
==================================================================
--- lib/libdm-common.c  (revision 206)
+++ lib/libdm-common.c  (local)
@@ -180,6 +180,27 @@
        return 1;
 }
 
+int _dm_task_set_uid(struct dm_task *dmt, uid_t uid)
+{
+       dmt->uid = uid;
+
+       return 1;
+}
+
+int _dm_task_set_gid(struct dm_task *dmt, gid_t gid)
+{
+       dmt->gid = gid;
+
+       return 1;
+}
+
+int _dm_task_set_mode(struct dm_task *dmt, mode_t mode)
+{
+       dmt->mode = mode;
+
+       return 1;
+}
+
 int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
                       const char *ttype, const char *params)
 {
=== lib/libdm-deptree.c
==================================================================
--- lib/libdm-deptree.c (revision 206)
+++ lib/libdm-deptree.c (local)
@@ -92,6 +92,9 @@
        int read_only;
        uint32_t major;
        uint32_t minor;
+       uid_t uid;
+       gid_t gid;
+       mode_t mode;
 
        unsigned segment_count;
        struct list segs;
@@ -366,6 +369,7 @@
 }
 
 static int _deps(struct dm_task **dmt, struct dm_pool *mem, uint32_t major, 
uint32_t minor,
+                uid_t uid, gid_t gid, mode_t mode,
                 const char **name, const char **uuid,
                 struct dm_info *info, struct dm_deps **deps)
 {
@@ -401,6 +405,24 @@
                goto failed;
        }
 
+       if (!_dm_task_set_uid(*dmt, uid)) {
+               log_error("_deps: failed to set uid for (%" PRIu32 ":%" PRIu32 
")",
+                         major, minor);
+               goto failed;
+       }
+
+       if (!_dm_task_set_gid(*dmt, gid)) {
+               log_error("_deps: failed to set gid for (%" PRIu32 ":%" PRIu32 
")",
+                         major, minor);
+               goto failed;
+       }
+
+       if (!_dm_task_set_mode(*dmt, mode)) {
+               log_error("_deps: failed to set mode for (%" PRIu32 ":%" PRIu32 
")",
+                         major, minor);
+               goto failed;
+       }
+
        if (!dm_task_run(*dmt)) {
                log_error("_deps: task run failed for (%" PRIu32 ":%" PRIu32 
")",
                          major, minor);
@@ -448,7 +470,8 @@
 
 static struct dm_tree_node *_add_dev(struct dm_tree *dtree,
                                     struct dm_tree_node *parent,
-                                    uint32_t major, uint32_t minor)
+                                    uint32_t major, uint32_t minor,
+                                    uid_t uid, gid_t gid, mode_t mode)
 {
        struct dm_task *dmt = NULL;
        struct dm_info info;
@@ -461,7 +484,7 @@
 
        /* Already in tree? */
        if (!(node = _find_dm_tree_node(dtree, major, minor))) {
-               if (!_deps(&dmt, dtree->mem, major, minor, &name, &uuid, &info, 
&deps))
+               if (!_deps(&dmt, dtree->mem, major, minor, uid, gid, mode, 
&name, &uuid, &info, &deps))
                        return_NULL;
 
                if (!(node = _create_dm_tree_node(dtree, name, uuid,
@@ -491,7 +514,7 @@
        /* Add dependencies to tree */
        for (i = 0; i < deps->count; i++)
                if (!_add_dev(dtree, node, MAJOR(deps->device[i]),
-                             MINOR(deps->device[i]))) {
+                             MINOR(deps->device[i]), uid, gid, mode)) {
                        node = NULL;
                        goto_out;
                }
@@ -560,6 +583,18 @@
                                            int clear_inactive,
                                            void *context)
 {
+       return _dm_tree_add_new_dev_mode(dtree, name, uuid, major, minor, 
DEVICE_UID, DEVICE_GID, DEVICE_MODE, read_only, clear_inactive, context);
+}
+
+struct dm_tree_node *_dm_tree_add_new_dev_mode(struct dm_tree *dtree,
+                                           const char *name,
+                                           const char *uuid,
+                                           uint32_t major, uint32_t minor,
+                                           uid_t uid, gid_t gid, mode_t mode,
+                                           int read_only,
+                                           int clear_inactive,
+                                           void *context)
+{
        struct dm_tree_node *dnode;
        struct dm_info info;
        const char *name2;
@@ -593,6 +628,9 @@
 
                dnode->props.major = major;
                dnode->props.minor = minor;
+                dnode->props.uid = uid;
+                dnode->props.gid = gid;
+                dnode->props.mode = mode;
                dnode->props.new_name = NULL;
        } else if (strcmp(name, dnode->name)) {
                /* Do we need to rename node? */
@@ -614,7 +652,7 @@
 
 int dm_tree_add_dev(struct dm_tree *dtree, uint32_t major, uint32_t minor)
 {
-       return _add_dev(dtree, &dtree->root, major, minor) ? 1 : 0;
+       return _add_dev(dtree, &dtree->root, major, minor, DEVICE_UID, 
DEVICE_GID, DEVICE_MODE) ? 1 : 0;
 }
 
 const char *dm_tree_node_get_name(struct dm_tree_node *node)
@@ -1155,6 +1193,12 @@
                goto out;
        }
 
+       if (!_dm_task_set_uid(dmt, dnode->props.uid) ||
+           !_dm_task_set_gid(dmt, dnode->props.gid) ||
+           !_dm_task_set_mode(dmt, dnode->props.mode)) {
+               log_error("Failed to set device permissions for %s creation.", 
dnode->name);
+               goto out;
+       }
        if (dnode->props.read_only && !dm_task_set_ro(dmt)) {
                log_error("Failed to set read only flag for %s", dnode->name);
                goto out;
@@ -1711,7 +1755,7 @@
                }
 
                /* FIXME Check correct macro use */
-               if (!(dev_node = _add_dev(node->dtree, node, 
MAJOR(info.st_rdev), MINOR(info.st_rdev))))
+               if (!(dev_node = _add_dev(node->dtree, node, 
MAJOR(info.st_rdev), MINOR(info.st_rdev), DEVICE_UID, DEVICE_GID, DEVICE_MODE)))
                        return_0;
        }
 
=== debian/changelog
==================================================================
--- debian/changelog    (revision 206)
+++ debian/changelog    (local)
@@ -1,3 +1,9 @@
+lvm2 (2.02.01-1.0permissions.1) UNRELEASED; urgency=low
+
+  * Set device permissions.
+
+ -- Bastian Blank <[EMAIL PROTECTED]>  Fri, 23 Dec 2005 22:00:21 +0100
+
 lvm2 (2.02.01-1) unstable; urgency=low
 
   * New upstream version.
=== doc/example.conf
==================================================================
--- doc/example.conf    (revision 206)
+++ doc/example.conf    (local)
@@ -257,6 +257,9 @@
     #   "@*" matches if any tag defined on the host is also set in the LV or VG
     #
     # volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
+
+    # Permissions to use for new devices
+    device_permissions = [ 0, 6, 0640 ]
 }
 
 
=== lib/activate/activate.c
==================================================================
--- lib/activate/activate.c     (revision 206)
+++ lib/activate/activate.c     (local)
@@ -723,6 +723,8 @@
 static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
                        int exclusive, int filter)
 {
+       const struct config_node *cn;
+       struct config_value *cv;
        struct logical_volume *lv;
        struct lvinfo info;
        int r;
@@ -753,6 +755,27 @@
        if (exclusive)
                lv->status |= ACTIVATE_EXCL;
 
+       cn = find_config_node(cmd->cft->root, "activation/device_permissions");
+        if (cn) {
+               cv = cn->v;
+               if (cv->type != CFG_INT)
+                       return 1;
+               lv->uid = cv->v.i;
+               cv = cv->next;
+               if (cv->type != CFG_INT)
+                       return 1;
+               lv->gid = cv->v.i;
+               cv = cv->next;
+               if (cv->type != CFG_INT)
+                       return 1;
+               lv->mode = cv->v.i;
+       }
+       else {
+               lv->uid = 0;
+               lv->gid = 0;
+               lv->mode = 0600;
+       }
+
        memlock_inc();
        r = _lv_activate_lv(lv);
        memlock_dec();
=== lib/activate/dev_manager.c
==================================================================
--- lib/activate/dev_manager.c  (revision 206)
+++ lib/activate/dev_manager.c  (local)
@@ -858,9 +858,10 @@
         * existing inactive table left behind.
         * Major/minor settings only apply to the visible layer.
         */
-       if (!(dnode = dm_tree_add_new_dev(dtree, name, dlid,
+       if (!(dnode = _dm_tree_add_new_dev_mode(dtree, name, dlid,
                                             layer ? lv->major : 0,
                                             layer ? lv->minor : 0,
+                                            lv->uid, lv->gid, lv->mode,
                                             _read_only_lv(lv),
                                             lv->vg->status & PRECOMMITTED,
                                             lvlayer)))
=== lib/metadata/metadata.h
==================================================================
--- lib/metadata/metadata.h     (revision 206)
+++ lib/metadata/metadata.h     (local)
@@ -279,6 +279,9 @@
        uint32_t read_ahead;
        int32_t major;
        int32_t minor;
+       uid_t uid;
+       gid_t gid;
+       mode_t mode;
 
        uint64_t size;
        uint32_t le_count;

Attachment: signature.asc
Description: Digital signature

Reply via email to