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 <waldi@debian.org> 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 <waldi@debian.org> 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