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:
Neil Brown 2006-05-15 06:02:41 +00:00
parent 1bfdbe01ff
commit 5bbb48424b
7 changed files with 198 additions and 70 deletions

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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' */

View File

@ -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
View File

@ -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);

View File

@ -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);