extern int
dm_addmap (int task, const char *name, const char *target,
- const char *params, uint64_t size, const char *uuid, int part) {
+ const char *params, uint64_t size, const char *uuid, int part,
+ mode_t mode, uid_t uid, gid_t gid) {
int r = 0;
struct dm_task *dmt;
char *prefixed_uuid = NULL;
goto addout;
}
+ if (!dm_task_set_mode(dmt, mode))
+ goto addout;
+ if (!dm_task_set_uid(dmt, uid))
+ goto addout;
+ if (!dm_task_set_gid(dmt, gid))
+ goto addout;
+
dm_task_no_open_count(dmt);
r = dm_task_run (dmt);
int dm_prereq (char *, int, int, int);
int dm_simplecmd (int, const char *, int);
int dm_addmap (int, const char *, const char *, const char *, uint64_t,
- const char *, int);
+ const char *, int, mode_t, uid_t, gid_t);
int dm_map_present (char *);
char * dm_mapname(int major, int minor);
dev_t dm_get_first_dep(char *devname);
DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
if (!dm_addmap(op, partname, DM_TARGET, params,
- slices[j].size, uuid, j+1)) {
+ slices[j].size, uuid, j+1,
+ buf.st_mode & 0777, buf.st_uid,
+ buf.st_gid)) {
fprintf(stderr, "create/reload failed on %s\n",
partname);
r++;
DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
dm_addmap(op, partname, DM_TARGET, params,
- slices[j].size, uuid, j+1);
+ slices[j].size, uuid, j+1,
+ buf.st_mode & 0777,
+ buf.st_uid, buf.st_gid);
if (op == DM_DEVICE_RELOAD)
dm_simplecmd(DM_DEVICE_RESUME,
conf->bindings_file = DEFAULT_BINDINGS_FILE;
conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
conf->flush_on_last_del = 0;
+ conf->attribute_flags = 0;
/*
* preload default hwtable
#ifndef _CONFIG_H
#define _CONFIG_H
+#include <sys/types.h>
+
#define ORIGIN_DEFAULT 0
#define ORIGIN_CONFIG 1
int minio;
int pg_timeout;
int flush_on_last_del;
+ int attribute_flags;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
};
struct config {
int force_reload;
int daemon;
int flush_on_last_del;
+ int attribute_flags;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
char * dev;
char * sysfs_dir;
select_minio(mpp);
select_no_path_retry(mpp);
select_pg_timeout(mpp);
+ select_mode(mpp);
+ select_uid(mpp);
+ select_gid(mpp);
/*
* assign paths to path groups -- start with no groups and all paths
break;
}
- r = dm_addmap_create(mpp->alias, mpp->params, mpp->size,
- mpp->wwid);
+ r = dm_addmap_create(mpp);
if (!r)
- r = dm_addmap_create_ro(mpp->alias, mpp->params,
- mpp->size, mpp->wwid);
+ r = dm_addmap_create_ro(mpp);
lock_multipath(mpp, 0);
break;
case ACT_RELOAD:
- r = dm_addmap_reload(mpp->alias, mpp->params, mpp->size, NULL);
+ r = dm_addmap_reload(mpp);
if (!r)
- r = dm_addmap_reload_ro(mpp->alias, mpp->params, mpp->size, NULL);
+ r = dm_addmap_reload_ro(mpp);
if (r)
r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias);
break;
case ACT_RESIZE:
- r = dm_addmap_reload(mpp->alias, mpp->params, mpp->size, NULL);
+ r = dm_addmap_reload(mpp);
if (!r)
- r = dm_addmap_reload_ro(mpp->alias, mpp->params, mpp->size, NULL);
+ r = dm_addmap_reload_ro(mpp);
if (r)
r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias);
break;
}
extern int
-dm_addmap (int task, const char *name, const char *target,
- const char *params, unsigned long long size, const char *uuid,
+dm_addmap (int task, const char *target, struct multipath *mpp, int use_uuid,
int ro) {
int r = 0;
struct dm_task *dmt;
if (!(dmt = dm_task_create (task)))
return 0;
- if (!dm_task_set_name (dmt, name))
+ if (!dm_task_set_name (dmt, mpp->alias))
goto addout;
- if (!dm_task_add_target (dmt, 0, size, target, params))
+ if (!dm_task_add_target (dmt, 0, mpp->size, target, mpp->params))
goto addout;
if (ro)
dm_task_set_ro(dmt);
- if (uuid){
- prefixed_uuid = MALLOC(UUID_PREFIX_LEN + strlen(uuid) + 1);
+ if (use_uuid && mpp->wwid){
+ prefixed_uuid = MALLOC(UUID_PREFIX_LEN + strlen(mpp->wwid) + 1);
if (!prefixed_uuid) {
condlog(0, "cannot create prefixed uuid : %s\n",
strerror(errno));
goto addout;
}
- sprintf(prefixed_uuid, UUID_PREFIX "%s", uuid);
+ sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid);
if (!dm_task_set_uuid(dmt, prefixed_uuid))
goto freeout;
}
+ if (mpp->attribute_flags & (1 << ATTR_MODE) &&
+ !dm_task_set_mode(dmt, mpp->mode))
+ goto freeout;
+ if (mpp->attribute_flags & (1 << ATTR_UID) &&
+ !dm_task_set_uid(dmt, mpp->uid))
+ goto freeout;
+ if (mpp->attribute_flags & (1 << ATTR_GID) &&
+ !dm_task_set_gid(dmt, mpp->gid))
+ goto freeout;
+
dm_task_no_open_count(dmt);
r = dm_task_run (dmt);
}
static int
-_dm_addmap_create (const char *name, const char *params,
- unsigned long long size, const char *uuid, int ro) {
+_dm_addmap_create (struct multipath *mpp, int ro) {
int r;
- r = dm_addmap(DM_DEVICE_CREATE, name, TGT_MPATH, params, size, uuid,
- ro);
+ r = dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, 1, ro);
/*
* DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
* Failing the second part leaves an empty map. Clean it up.
*/
- if (!r && dm_map_present(name)) {
+ if (!r && dm_map_present(mpp->alias)) {
condlog(3, "%s: failed to load map (a path might be in use)",
- name);
- dm_flush_map(name);
+ mpp->alias);
+ dm_flush_map(mpp->alias);
}
return r;
}
#define ADDMAP_RO 1
extern int
-dm_addmap_create (const char *name, const char *params,
- unsigned long long size, const char *uuid) {
- return _dm_addmap_create(name, params, size, uuid, ADDMAP_RW);
+dm_addmap_create (struct multipath *mpp) {
+ return _dm_addmap_create(mpp, ADDMAP_RW);
}
extern int
-dm_addmap_create_ro (const char *name, const char *params,
- unsigned long long size, const char *uuid) {
- return _dm_addmap_create(name, params, size, uuid, ADDMAP_RO);
+dm_addmap_create_ro (struct multipath *mpp) {
+ return _dm_addmap_create(mpp, ADDMAP_RO);
}
extern int
-dm_addmap_reload (const char *name, const char *params,
- unsigned long long size, const char *uuid) {
- return dm_addmap(DM_DEVICE_RELOAD, name, TGT_MPATH, params, size, uuid,
- ADDMAP_RW);
+dm_addmap_reload (struct multipath *mpp) {
+ return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, 0, ADDMAP_RW);
}
extern int
-dm_addmap_reload_ro (const char *name, const char *params,
- unsigned long long size, const char *uuid) {
- return dm_addmap(DM_DEVICE_RELOAD, name, TGT_MPATH, params, size, uuid,
- ADDMAP_RO);
+dm_addmap_reload_ro (struct multipath *mpp) {
+ return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, 0, ADDMAP_RO);
}
extern int
+#ifndef _DEVMAPPER_H
+#define _DEVMAPPER_H
+
+#include "structs.h"
+
#define TGT_MPATH "multipath"
#define TGT_PART "linear"
int dm_prereq (void);
int dm_simplecmd_flush (int, const char *);
int dm_simplecmd_noflush (int, const char *);
-int dm_addmap_create (const char *, const char *,
- unsigned long long size, const char *uuid);
-int dm_addmap_create_ro (const char *, const char *,
- unsigned long long size, const char *uuid);
-int dm_addmap_reload (const char *, const char *,
- unsigned long long size, const char *uuid);
-int dm_addmap_reload_ro (const char *, const char *,
- unsigned long long size, const char *uuid);
+int dm_addmap_create (struct multipath *mpp);
+int dm_addmap_create_ro (struct multipath *mpp);
+int dm_addmap_reload (struct multipath *mpp);
+int dm_addmap_reload_ro (struct multipath *mpp);
int dm_map_present (const char *);
int dm_get_map(char *, unsigned long long *, char *);
int dm_get_status(char *, char *);
int dm_get_info (char * mapname, struct dm_info ** dmi);
int dm_rename (char * old, char * new);
int dm_get_name(char * uuid, char * name);
+
+#endif /* _DEVMAPPER_H */
* Copyright (c) 2005 Benjamin Marzinski, Redhat
* Copyright (c) 2005 Kiyoshi Ueda, NEC
*/
+#include <sys/types.h>
+#include <pwd.h>
+
#include "checkers.h"
#include "vector.h"
#include "hwtable.h"
}
static int
+def_mode_handler(vector strvec)
+{
+ mode_t mode;
+ char *buff;
+
+ buff = set_value(strvec);
+
+ if (!buff)
+ return 1;
+
+ if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) {
+ conf->attribute_flags |= (1 << ATTR_MODE);
+ conf->mode = mode;
+ }
+
+ FREE(buff);
+ return 0;
+}
+
+static int
+def_uid_handler(vector strvec)
+{
+ uid_t uid;
+ char *buff;
+ char passwd_buf[1024];
+ struct passwd info, *found;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+ if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
+ conf->attribute_flags |= (1 << ATTR_UID);
+ conf->uid = info.pw_uid;
+ }
+ else if (sscanf(buff, "%u", &uid) == 1){
+ conf->attribute_flags |= (1 << ATTR_UID);
+ conf->uid = uid;
+ }
+
+ FREE(buff);
+ return 0;
+}
+
+static int
+def_gid_handler(vector strvec)
+{
+ gid_t gid;
+ char *buff;
+ char passwd_buf[1024];
+ struct passwd info, *found;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+
+ if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
+ conf->attribute_flags |= (1 << ATTR_GID);
+ conf->gid = info.pw_gid;
+ }
+ else if (sscanf(buff, "%u", &gid) == 1){
+ conf->attribute_flags |= (1 << ATTR_GID);
+ conf->gid = gid;
+ }
+ FREE(buff);
+ return 0;
+}
+
+static int
def_weight_handler(vector strvec)
{
char * buff;
}
static int
+mp_mode_handler(vector strvec)
+{
+ mode_t mode;
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+ char *buff;
+
+ if (!mpe)
+ return 1;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+ if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) {
+ mpe->attribute_flags |= (1 << ATTR_MODE);
+ mpe->mode = mode;
+ }
+
+ FREE(buff);
+ return 0;
+}
+
+static int
+mp_uid_handler(vector strvec)
+{
+ uid_t uid;
+ char *buff;
+ char passwd_buf[1024];
+ struct passwd info, *found;
+
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+
+ if (!mpe)
+ return 1;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+
+ if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
+ mpe->attribute_flags |= (1 << ATTR_UID);
+ mpe->uid = info.pw_uid;
+ }
+ else if (sscanf(buff, "%u", &uid) == 1){
+ mpe->attribute_flags |= (1 << ATTR_UID);
+ mpe->uid = uid;
+ }
+ FREE(buff);
+ return 0;
+}
+
+static int
+mp_gid_handler(vector strvec)
+{
+ gid_t gid;
+ char *buff;
+ char passwd_buf[1024];
+ struct passwd info, *found;
+
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+
+ if (!mpe)
+ return 1;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+
+ if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
+ mpe->attribute_flags |= (1 << ATTR_GID);
+ mpe->gid = info.pw_gid;
+ }
+ else if (sscanf(buff, "%u", &gid) == 1) {
+ mpe->attribute_flags |= (1 << ATTR_GID);
+ mpe->gid = gid;
+ }
+ FREE(buff);
+ return 0;
+}
+
+static int
mp_weight_handler(vector strvec)
{
struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
}
static int
+snprint_mp_mode(char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if ((mpe->attribute_flags & (1 << ATTR_MODE)) == 0)
+ return 0;
+ return snprintf(buff, len, "0%o", mpe->mode);
+}
+
+static int
+snprint_mp_uid(char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if ((mpe->attribute_flags & (1 << ATTR_UID)) == 0)
+ return 0;
+ return snprintf(buff, len, "0%o", mpe->uid);
+}
+
+static int
+snprint_mp_gid(char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if ((mpe->attribute_flags & (1 << ATTR_GID)) == 0)
+ return 0;
+ return snprintf(buff, len, "0%o", mpe->gid);
+}
+
+static int
snprint_mp_rr_weight (char * buff, int len, void * data)
{
struct mpentry * mpe = (struct mpentry *)data;
}
static int
+snprint_def_mode(char * buff, int len, void * data)
+{
+ if ((conf->attribute_flags & (1 << ATTR_MODE)) == 0)
+ return 0;
+ return snprintf(buff, len, "0%o", conf->mode);
+}
+
+static int
+snprint_def_uid(char * buff, int len, void * data)
+{
+ if ((conf->attribute_flags & (1 << ATTR_UID)) == 0)
+ return 0;
+ return snprintf(buff, len, "0%o", conf->uid);
+}
+
+static int
+snprint_def_gid(char * buff, int len, void * data)
+{
+ if ((conf->attribute_flags & (1 << ATTR_GID)) == 0)
+ return 0;
+ return snprintf(buff, len, "0%o", conf->gid);
+}
+
+static int
snprint_def_rr_weight (char * buff, int len, void * data)
{
if (!conf->rr_weight)
install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names);
+ install_keyword("mode", &def_mode_handler, &snprint_def_mode);
+ install_keyword("uid", &def_uid_handler, &snprint_def_uid);
+ install_keyword("gid", &def_gid_handler, &snprint_def_gid);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
__deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_rr_min_io);
install_keyword("pg_timeout", &mp_pg_timeout_handler, &snprint_mp_pg_timeout);
install_keyword("flush_on_last_del", &mp_flush_on_last_del_handler, &snprint_mp_flush_on_last_del);
+ install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
+ install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
+ install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
install_sublevel_end();
}
group_by_node_name
};
+extern int
+select_mode (struct multipath *mp)
+{
+ if (mp->mpe && (mp->mpe->attribute_flags & (1 << ATTR_MODE))) {
+ mp->attribute_flags |= (1 << ATTR_MODE);
+ mp->mode = mp->mpe->mode;
+ condlog(3, "mode = 0%o (LUN setting)", mp->mode);
+ }
+ else if (conf->attribute_flags & (1 << ATTR_MODE)) {
+ mp->attribute_flags |= (1 << ATTR_MODE);
+ mp->mode = conf->mode;
+ condlog(3, "mode = 0%o (config file default)", mp->mode);
+ }
+ else
+ mp->attribute_flags &= ~(1 << ATTR_MODE);
+ return 0;
+}
+
+extern int
+select_uid (struct multipath *mp)
+{
+ if (mp->mpe && (mp->mpe->attribute_flags & (1 << ATTR_UID))) {
+ mp->attribute_flags |= (1 << ATTR_UID);
+ mp->uid = mp->mpe->uid;
+ condlog(3, "uid = %u (LUN setting)", mp->uid);
+ }
+ else if (conf->attribute_flags & (1 << ATTR_UID)) {
+ mp->attribute_flags |= (1 << ATTR_UID);
+ mp->uid = conf->uid;
+ condlog(3, "uid = %u (config file default)", mp->uid);
+ }
+ else
+ mp->attribute_flags &= ~(1 << ATTR_UID);
+ return 0;
+}
+
+extern int
+select_gid (struct multipath *mp)
+{
+ if (mp->mpe && (mp->mpe->attribute_flags & (1 << ATTR_GID))) {
+ mp->attribute_flags |= (1 << ATTR_GID);
+ mp->gid = mp->mpe->gid;
+ condlog(3, "gid = %u (LUN setting)", mp->gid);
+ }
+ else if (conf->attribute_flags & (1 << ATTR_GID)) {
+ mp->attribute_flags |= (1 << ATTR_GID);
+ mp->gid = conf->gid;
+ condlog(3, "gid = %u (config file default)", mp->gid);
+ }
+ else
+ mp->attribute_flags &= ~(1 << ATTR_GID);
+ return 0;
+}
+
/*
* selectors :
* traverse the configuration layers from most specific to most generic
int select_pg_timeout(struct multipath *mp);
int select_flush_on_last_del(struct multipath *mp);
int select_minio(struct multipath *mp);
+int select_mode(struct multipath *mp);
+int select_uid(struct multipath *mp);
+int select_gid(struct multipath *mp);
#ifndef _STRUCTS_H
#define _STRUCTS_H
+#include <sys/types.h>
+
#define WWID_SIZE 128
#define SERIAL_SIZE 64
#define NODE_NAME_SIZE 19
PGTIMEOUT_NONE
};
+enum attribute_bits {
+ ATTR_UID,
+ ATTR_GID,
+ ATTR_MODE,
+};
enum flush_states {
FLUSH_UNDEF,
int minio;
int pg_timeout;
int flush_on_last_del;
+ int attribute_flags;
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
unsigned long long size;
vector paths;
vector pg;
# # default : no
# user_friendly_names no
#
+# #
+# # name : mode
+# # scope : multipath
+# # desc : The mode to use for the multipath device nodes, in octal.
+# # values : 0000 - 0777
+# # default : determined by the process
+# mode 0644
+#
+# #
+# # name : uid
+# # scope : multipath
+# # desc : The user id to use for the multipath device nodes. You
+# # may use either the numeric or symbolic uid
+# # values : <user_id>
+# # default : determined by the process
+# uid 0
+#
+# #
+# # name : gid
+# # scope : multipath
+# # desc : The group id to user for the multipath device nodes. You
+# # may use either the numeric or symbolic gid
+# # values : <group_id>
+# # default : determined by the process
+# gid disk
+#
#}
#
##
# # default : no
# #
# flush_on_last_del yes
+#
+# #
+# # name : mode
+# # scope : multipath
+# # desc : The mode to use for the multipath device nodes, in
+# # octal.
+# # values : 0000 - 0777
+# # default : determined by the process
+# mode 0644
+#
+# #
+# # name : uid
+# # scope : multipath
+# # desc : The user id to use for the multipath device nodes.
+# # You may use either the numeric or symbolic uid
+# # values : <user_id>
+# # default : determined by the process
+# uid 0
+#
+# #
+# # name : gid
+# # scope : multipath
+# # desc : The group id to user for the multipath device nodes.
+# # You may use either the numeric or symbolic gid
+# # values : <group_id>
+# # default : determined by the process
+# gid 0
+#
# }
# multipath {
# wwid 1DEC_____321816758474
# failback immediate
# no_path_retry fail
# user_friendly_names no
+# mode 644
+# uid 0
+# gid disk
#}
#blacklist {
# wwid 26353900f02796769