[systemd-devel] [PATCH ] Adding /etc/fstab.d/*.fstab support

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Fri Jan 20 00:59:26 PST 2012


On 01/20/2012 07:52 AM, Masatake YAMATO wrote:
> mount command in the latest version of util-linux(2.21-rc1[1])
> supports /etc/fstab.d; mount command reads /etc/fstab.d/*.fstab
> files as if they are written in /etc/fstab.
Cool.

> --- a/src/mount.c
> +++ b/src/mount.c
> @@ -19,6 +19,10 @@
>     along with systemd; If not, see<http://www.gnu.org/licenses/>.
>   ***/
>
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#endif
> +
Indentation here seems to be different than in the surrounding chunk.
>   #include<errno.h>
>   #include<stdio.h>
>   #include<mntent.h>
> @@ -1503,7 +1507,7 @@ static int mount_find_pri(char *options) {
>           return (int) r;
>   }
>
> -static int mount_load_etc_fstab(Manager *m) {
> +static int mount_load_etc_fstab(Manager *m, const char* fname) {
>           FILE *f;
>           int r = 0;
>           struct mntent* me;
> @@ -1511,7 +1515,7 @@ static int mount_load_etc_fstab(Manager *m) {
>           assert(m);
>
>           errno = 0;
> -        if (!(f = setmntent("/etc/fstab", "r")))
> +        if (!(f = setmntent(fname, "r")))
Here too.

>                   return -errno;
>
>           while ((me = getmntent(f))) {
> @@ -1565,6 +1569,68 @@ finish:
>           return r;
>   }
>
> +/* This code is based on mnt_table_parse_dir()
> +   in util-linux/libmount/src/tab_parse.c */
> +static int mount_load_etc_fstab_d(Manager *m, const char* dname) {
> +        DIR* dir;
> +        int n, i, r = 0;
> +        struct dirent **namelist = NULL;
> +
> +        n = scandir(dname,&namelist, NULL, versionsort);
> +        if (n<= 0)
> +                return 0;
> +
> +        dir = opendir(dname);
> +        if (!dir) {
> +                r = -errno;
> +                goto out;
> +        }
> +
> +        for (i = 0; i<  n; i++) {
> +                struct dirent *d = namelist[i];
> +                struct stat st;
> +		size_t namesz;
> +		FILE *f;
And here again...
> +                char fstab[PATH_MAX];
> +                int rc;
> +
> +#ifdef _DIRENT_HAVE_D_TYPE
> +		if (d->d_type != DT_UNKNOWN&&  d->d_type != DT_REG&&
> +		    d->d_type != DT_LNK)
> +			continue;
> +#endif
> +                if (*d->d_name == '.')
> +			continue;
> +
> +#define MNT_MNTTABDIR_EXT	".fstab"
> +#define MNT_MNTTABDIR_EXTSIZ	(sizeof(MNT_MNTTABDIR_EXT) - 1)
> +
> +		namesz = strlen(d->d_name);
> +                if (!namesz || namesz<  MNT_MNTTABDIR_EXTSIZ + 1 ||
> +		    strcmp(d->d_name + (namesz - MNT_MNTTABDIR_EXTSIZ),
> +                           MNT_MNTTABDIR_EXT))
> +                        continue;
> +
> +                if (fstatat(dirfd(dir), d->d_name,&st, 0) ||
> +		    !S_ISREG(st.st_mode))
> +			continue;
> +
> +                rc = snprintf(fstab, sizeof(fstab), "%s/%s", dname, d->d_name);
> +                if (rc<  0 || (size_t) rc>= sizeof(fstab))
> +                        continue;
> +
> +                mount_load_etc_fstab(m, fstab);
> +        }
> +
> + out:
> +        if (dir)
> +                closedir(dir);
> +        for (i = 0; i<  n; i++)
> +                free(namelist[i]);
> +        free(namelist);
> +        return r;
> +}
> +
>   static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
>           int r = 0;
>           unsigned i;
> @@ -1672,9 +1738,13 @@ static int mount_enumerate(Manager *m) {
>                           return -errno;
>           }
>
> -        if ((r = mount_load_etc_fstab(m))<  0)
> +        if ((r = mount_load_etc_fstab(m, "/etc/fstab"))<  0)
>                   goto fail;
>
> +        /* No need to check the return value here: /etc/fstab.d is optional. */
> +        mount_load_etc_fstab_d(m,"/etc/fstab.d");
I think that you only want to ignore ENOENT, and fail at least on some
errors. Out of memory --> fail, can't read the file --> warn?
If all errors were ignored, then mount_load_etc_fstab should be changed 
to return void, but I think some errors should be caught.

> +
> +
Extra line here.
>           if ((r = mount_load_proc_self_mountinfo(m, false))<  0)
>                   goto fail;

Best,
Zbyszek


More information about the systemd-devel mailing list