Allow default creation info to to be stored in mdadm.conf
Default owner, group, mode and 'auto' flag can be given in a 'CREATE' line. Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
parent
1bfdbe01ff
commit
5bbb48424b
|
@ -8,6 +8,8 @@ Changes Prior to this release
|
|||
- When creating a bitmap file, choose a chunksize to limit number
|
||||
of bitmap chunks to 2 million. More than this can cause kmalloc
|
||||
failure.
|
||||
- New 'CREATE' line in mdadm.conf for defaults such as owner, group,
|
||||
mode and auto-flag
|
||||
|
||||
Changes Prior to 2.4.1 release
|
||||
- Honour --write-mostly when adding to an array without persistent
|
||||
|
|
20
Makefile
20
Makefile
|
@ -40,10 +40,17 @@ KLIBC_GCC = gcc -nostdinc -iwithprefix include -I$(KLIBC)/klibc/include -I$(KLIB
|
|||
CC = $(CROSS_COMPILE)gcc
|
||||
CXFLAGS = -ggdb
|
||||
CWFLAGS = -Wall -Werror -Wstrict-prototypes
|
||||
|
||||
ifdef DEBIAN
|
||||
CPPFLAGS= -DDEBIAN
|
||||
else
|
||||
CPPFLAGS=
|
||||
endif
|
||||
|
||||
SYSCONFDIR = /etc
|
||||
CONFFILE = $(SYSCONFDIR)/mdadm.conf
|
||||
MAILCMD =/usr/sbin/sendmail -t
|
||||
CFLAGS = $(CWFLAGS) -DCONFFILE=\"$(CONFFILE)\" $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\"
|
||||
CFLAGS = $(CWFLAGS) $(STATIC) $(CPPFLAGS) -DCONFFILE=\"$(CONFFILE)\" $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\"
|
||||
|
||||
# If you want a static binary, you might uncomment these
|
||||
# LDFLAGS = -static
|
||||
|
@ -76,11 +83,14 @@ all : mdadm mdadm.man md.man mdadm.conf.man
|
|||
everything: all mdadm.static mdadm.uclibc swap_super test_stripe mdassemble mdassemble.uclibc mdassemble.static mdassemble.man
|
||||
# mdadm.tcc doesn't work..
|
||||
|
||||
mdadm : $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o mdadm $^
|
||||
mdadm : rmconf $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o mdadm $(OBJS)
|
||||
|
||||
mdadm.static : $(OBJS)
|
||||
$(CC) $(LDFLAGS) -static -o mdadm.static $^
|
||||
mdadm.static : STATIC=-DSTATIC
|
||||
mdadm.static : rmconf $(OBJS)
|
||||
$(CC) $(LDFLAGS) -DSTATIC -static -o mdadm.static $(OBJS)
|
||||
rmconf:
|
||||
rm -f config.o
|
||||
|
||||
mdadm.tcc : $(SRCS) mdadm.h
|
||||
$(TCC) -o mdadm.tcc $(SRCS)
|
||||
|
|
148
config.c
148
config.c
|
@ -33,6 +33,8 @@
|
|||
#include <glob.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
/*
|
||||
* Read the config file
|
||||
|
@ -77,7 +79,10 @@
|
|||
char DefaultConfFile[] = CONFFILE;
|
||||
char DefaultAltConfFile[] = CONFFILE2;
|
||||
|
||||
char *keywords[] = { "device", "array", "mailaddr", "program", "mailfrom", NULL };
|
||||
char *keywords[] = { "devices", "array",
|
||||
"mailaddr", "program", "mailfrom",
|
||||
"create",
|
||||
NULL };
|
||||
|
||||
/*
|
||||
* match_keyword returns an index into the keywords array, or -1 for no match
|
||||
|
@ -240,6 +245,112 @@ mddev_dev_t load_partitions(void)
|
|||
return rv;
|
||||
}
|
||||
|
||||
struct createinfo createinfo = {
|
||||
#ifdef DEBIAN
|
||||
.gid = 6, /* disk */
|
||||
.mode = 0660,
|
||||
#else
|
||||
.mode = 0600,
|
||||
#endif
|
||||
};
|
||||
|
||||
int parse_auto(char *str, char *msg)
|
||||
{
|
||||
int autof;
|
||||
if (str == NULL || *str == 0)
|
||||
autof = -2;
|
||||
else if (strcasecmp(str,"no")==0)
|
||||
autof = -3;
|
||||
else if (strcasecmp(str,"yes")==0)
|
||||
autof = -2;
|
||||
else if (strcasecmp(str,"md")==0)
|
||||
autof = -1;
|
||||
else {
|
||||
/* There might be digits, and maybe a hypen, at the end */
|
||||
char *e = str + strlen(str);
|
||||
int num = 4;
|
||||
int len;
|
||||
while (e > str && isdigit(e[-1]))
|
||||
e--;
|
||||
if (*e) {
|
||||
num = atoi(e);
|
||||
if (num <= 0) num = 1;
|
||||
}
|
||||
if (e > str && e[-1] == '-')
|
||||
e--;
|
||||
len = e - str;
|
||||
if ((len == 3 && strncasecmp(str,"mdp",3)==0) ||
|
||||
(len == 1 && strncasecmp(str,"p",1)==0) ||
|
||||
(len >= 4 && strncasecmp(str,"part",4)==0))
|
||||
autof = num;
|
||||
else {
|
||||
fprintf(stderr, Name ": %s arg of \"%s\" unrecognised: use no,yes,md,mdp,part\n"
|
||||
" optionally followed by a number.\n",
|
||||
msg, str);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
return autof;
|
||||
}
|
||||
static void createline(char *line)
|
||||
{
|
||||
char *w;
|
||||
char *ep;
|
||||
|
||||
for (w=dl_next(line); w!=line; w=dl_next(w)) {
|
||||
if (strncasecmp(w, "auto=", 5) == 0)
|
||||
createinfo.autof = parse_auto(w+5, "auto=");
|
||||
else if (strncasecmp(w, "owner=", 6) == 0) {
|
||||
if (w[6] == 0) {
|
||||
fprintf(stderr, Name ": missing owner name\n");
|
||||
continue;
|
||||
}
|
||||
createinfo.uid = strtoul(w+6, &ep, 10);
|
||||
if (*ep != 0) {
|
||||
#ifndef STATIC
|
||||
struct passwd *pw;
|
||||
/* must be a name */
|
||||
pw = getpwnam(w+6);
|
||||
if (pw)
|
||||
createinfo.uid = pw->pw_uid;
|
||||
else
|
||||
#endif /* STATIC */
|
||||
fprintf(stderr, Name ": CREATE user %s not found\n", w+6);
|
||||
}
|
||||
} else if (strncasecmp(w, "group=", 6) == 0) {
|
||||
if (w[6] == 0) {
|
||||
fprintf(stderr, Name ": missing group name\n");
|
||||
continue;
|
||||
}
|
||||
createinfo.gid = strtoul(w+6, &ep, 10);
|
||||
if (*ep != 0) {
|
||||
#ifndef STATIC
|
||||
struct group *gr;
|
||||
/* must be a name */
|
||||
gr = getgrnam(w+6);
|
||||
if (gr)
|
||||
createinfo.gid = gr->gr_gid;
|
||||
else
|
||||
#endif /* STATIC */
|
||||
fprintf(stderr, Name ": CREATE group %s not found\n", w+6);
|
||||
}
|
||||
} else if (strncasecmp(w, "mode=", 5) == 0) {
|
||||
if (w[5] == 0) {
|
||||
fprintf(stderr, Name ": missing CREATE mode\n");
|
||||
continue;
|
||||
}
|
||||
createinfo.mode = strtoul(w+5, &ep, 8);
|
||||
if (*ep != 0) {
|
||||
createinfo.mode = 0600;
|
||||
fprintf(stderr, Name ": unrecognised CREATE mode %s\n",
|
||||
w+5);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, Name ": unrecognised word on CREATE line: %s\n",
|
||||
w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void devline(char *line)
|
||||
{
|
||||
|
@ -364,32 +475,7 @@ void arrayline(char *line)
|
|||
fprintf(stderr, Name ": metadata format %s unknown, ignored.\n", w+9);
|
||||
} else if (strncasecmp(w, "auto=", 5) == 0 ) {
|
||||
/* whether to create device special files as needed */
|
||||
if (strcasecmp(w+5, "no")==0)
|
||||
mis.autof = 0;
|
||||
else if (strcasecmp(w+5,"yes")==0 || strcasecmp(w+5,"md")==0)
|
||||
mis.autof = -1;
|
||||
else {
|
||||
/* There might be digits, and maybe a hyphen, at the end */
|
||||
char *e = w+5 + strlen(w+5);
|
||||
int num = 4;
|
||||
int len;
|
||||
while (e > w+5 && isdigit(e[-1]))
|
||||
e--;
|
||||
if (*e) {
|
||||
num = atoi(e);
|
||||
if (num <= 0) num = 1;
|
||||
}
|
||||
if (e > w+5 && e[-1] == '-')
|
||||
e--;
|
||||
len = e - (w+5);
|
||||
if ((len == 3 && strncasecmp(w+5,"mdp",3)==0) ||
|
||||
(len == 1 && strncasecmp(w+5,"p",1)==0) ||
|
||||
(len >= 4 && strncasecmp(w+5,"part",4)==0))
|
||||
mis.autof = num;
|
||||
else
|
||||
fprintf(stderr, Name ": auto type of \"%s\" ignored for %s\n",
|
||||
w+5, mis.devname?mis.devname:"unlabeled-array");
|
||||
}
|
||||
mis.autof = parse_auto(w+5, "auto type");
|
||||
} else {
|
||||
fprintf(stderr, Name ": unrecognised word on ARRAY line: %s\n",
|
||||
w);
|
||||
|
@ -513,6 +599,9 @@ void load_conffile(char *conffile)
|
|||
case 4: /* MAILFROM */
|
||||
mailfromline(line);
|
||||
break;
|
||||
case 5: /* CREATE */
|
||||
createline(line);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, Name ": Unknown keyword %s\n", line);
|
||||
}
|
||||
|
@ -542,6 +631,11 @@ char *conf_get_program(char *conffile)
|
|||
return alert_program;
|
||||
}
|
||||
|
||||
struct createinfo *conf_get_create_info(char *conffile)
|
||||
{
|
||||
load_conffile(conffile);
|
||||
return &createinfo;
|
||||
}
|
||||
|
||||
mddev_ident_t conf_get_ident(char *conffile, char *dev)
|
||||
{
|
||||
|
|
37
mdadm.c
37
mdadm.c
|
@ -75,7 +75,8 @@ int main(int argc, char *argv[])
|
|||
int force = 0;
|
||||
int test = 0;
|
||||
int assume_clean = 0;
|
||||
int autof = 0; /* -2 means create device based on name:
|
||||
int autof = 0; /* -3 means don't create anything,
|
||||
* -2 means create device based on name:
|
||||
* if it ends mdN, then non-partitioned array N
|
||||
* if it ends dN, then partitions array N
|
||||
* -1 means create non-partitioned, choose N
|
||||
|
@ -482,39 +483,7 @@ int main(int argc, char *argv[])
|
|||
case O(CREATE,'a'):
|
||||
case O(BUILD,'a'):
|
||||
case O(ASSEMBLE,'a'): /* auto-creation of device node */
|
||||
if (optarg == NULL)
|
||||
autof = -2;
|
||||
else if (strcasecmp(optarg,"no")==0)
|
||||
autof = 0;
|
||||
else if (strcasecmp(optarg,"yes")==0)
|
||||
autof = -2;
|
||||
else if (strcasecmp(optarg,"md")==0)
|
||||
autof = -1;
|
||||
else {
|
||||
/* There might be digits, and maybe a hypen, at the end */
|
||||
char *e = optarg + strlen(optarg);
|
||||
int num = 4;
|
||||
int len;
|
||||
while (e > optarg && isdigit(e[-1]))
|
||||
e--;
|
||||
if (*e) {
|
||||
num = atoi(e);
|
||||
if (num <= 0) num = 1;
|
||||
}
|
||||
if (e > optarg && e[-1] == '-')
|
||||
e--;
|
||||
len = e - optarg;
|
||||
if ((len == 3 && strncasecmp(optarg,"mdp",3)==0) ||
|
||||
(len == 1 && strncasecmp(optarg,"p",1)==0) ||
|
||||
(len >= 4 && strncasecmp(optarg,"part",4)==0))
|
||||
autof = num;
|
||||
else {
|
||||
fprintf(stderr, Name ": --auto flag arg of \"%s\" unrecognised: use no,yes,md,mdp,part\n"
|
||||
" optionally followed by a number.\n",
|
||||
optarg);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
autof = parse_auto(optarg, "--auto flag");
|
||||
continue;
|
||||
|
||||
case O(BUILD,'f'): /* force honouring '-n 1' */
|
||||
|
|
38
mdadm.conf.5
38
mdadm.conf.5
|
@ -212,6 +212,41 @@ There should only be one
|
|||
.B program
|
||||
line and it should be give only one program.
|
||||
|
||||
|
||||
.TP
|
||||
.B CREATE
|
||||
The
|
||||
.B create
|
||||
line gives default values to be used when creating device entries for
|
||||
arrays.
|
||||
These include:
|
||||
|
||||
.RS 4
|
||||
.TP
|
||||
.B owner=
|
||||
.TP
|
||||
.B group=
|
||||
These can give user/group ids or names to use instead of system
|
||||
defaults (root/wheel or root/disk).
|
||||
.TP
|
||||
.B mode=
|
||||
An octal file mode such as 0660 can be given to override the default
|
||||
of 0600.
|
||||
.TP
|
||||
.B auto=
|
||||
This corresponds to the
|
||||
.B --auto
|
||||
flag to mdadm. Give
|
||||
.BR yes ,
|
||||
.BR md ,
|
||||
.BR mdp ,
|
||||
.B part
|
||||
- possibly followed by a number of partitions - to indicate how
|
||||
missing device entries should be created.
|
||||
|
||||
.RE
|
||||
|
||||
|
||||
.SH EXAMPLE
|
||||
DEVICE /dev/sd[bcdjkl]1
|
||||
.br
|
||||
|
@ -254,7 +289,8 @@ ARRAY /dev/md/home UUID=9187a482:5dde19d9:eea3cc4a:d646ab8b
|
|||
MAILADDR root@mydomain.tld
|
||||
.br
|
||||
PROGRAM /usr/sbin/handle-mdadm-events
|
||||
|
||||
.br
|
||||
CREATE group=system mode=0640 auto=part-8
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR mdadm (8),
|
||||
|
|
10
mdadm.h
10
mdadm.h
|
@ -99,6 +99,13 @@ struct mdinfo {
|
|||
int new_level, delta_disks, new_layout, new_chunk;
|
||||
};
|
||||
|
||||
struct createinfo {
|
||||
int uid;
|
||||
int gid;
|
||||
int autof;
|
||||
int mode;
|
||||
};
|
||||
|
||||
#define Name "mdadm"
|
||||
|
||||
enum mode {
|
||||
|
@ -366,9 +373,10 @@ extern int get_mdp_major(void);
|
|||
extern int dev_open(char *dev, int flags);
|
||||
extern int is_standard(char *dev, int *nump);
|
||||
|
||||
|
||||
extern int parse_auto(char *str, char *msg);
|
||||
extern mddev_ident_t conf_get_ident(char *conffile, char *dev);
|
||||
extern mddev_dev_t conf_get_devs(char *conffile);
|
||||
extern struct createinfo *conf_get_create_info(char *conffile);
|
||||
extern char *conf_get_mailaddr(char *conffile);
|
||||
extern char *conf_get_mailfrom(char *conffile);
|
||||
extern char *conf_get_program(char *conffile);
|
||||
|
|
13
mdopen.c
13
mdopen.c
|
@ -82,7 +82,7 @@ void make_parts(char *dev, int cnt)
|
|||
* If it exists and is not an md device, is not the right type (partitioned or not),
|
||||
* or is currently in-use, we remove the device, but remember the owner and mode.
|
||||
* If it now doesn't exist, we find a new md array and create the device.
|
||||
* Default ownership is user=0, group=0 perm=0600
|
||||
* Default ownership/mode comes from config file.
|
||||
*/
|
||||
int open_mddev(char *dev, int autof)
|
||||
{
|
||||
|
@ -93,8 +93,12 @@ int open_mddev(char *dev, int autof)
|
|||
int must_remove = 0;
|
||||
struct mdstat_ent *mdlist;
|
||||
int num;
|
||||
struct createinfo *ci = conf_get_create_info(NULL);
|
||||
|
||||
if (autof) {
|
||||
if (autof == 0)
|
||||
autof = ci->autof;
|
||||
|
||||
if (autof && autof != -3) {
|
||||
/* autof is set, so we need to check that the name is ok,
|
||||
* and possibly create one if not
|
||||
*/
|
||||
|
@ -212,6 +216,11 @@ int open_mddev(char *dev, int autof)
|
|||
perror("chown");
|
||||
if (chmod(dev, stb.st_mode & 07777))
|
||||
perror("chmod");
|
||||
} else {
|
||||
if (chown(dev, ci->uid, ci->gid))
|
||||
perror("chown");
|
||||
if (chmod(dev, ci->mode))
|
||||
perror("chmod");
|
||||
}
|
||||
stat(dev, &stb);
|
||||
add_dev(dev, &stb, 0, NULL);
|
||||
|
|
Loading…
Reference in New Issue