[lxc-devel] [PATCH] utils: reimplement/fix mkdir_p()
Serge Hallyn
serge.hallyn at ubuntu.com
Wed Apr 17 16:00:24 UTC 2013
Quoting Richard Weinberger (richard at nod.at):
> Reimplement mkdir_p() such that it:
> ...handles relativ paths correctly. (currently it crashes)
> ...does not rely on dirname().
> ...is not recursive.
> ...is shorter. ;-)
Looks good, thanks. Yeah I prefer non-recursive. Three
comments though,
> Signed-off-by: Richard Weinberger <richard at nod.at>
> ---
> src/lxc/utils.c | 48 +++++++++++++++++-------------------------------
> 1 file changed, 17 insertions(+), 31 deletions(-)
>
> diff --git a/src/lxc/utils.c b/src/lxc/utils.c
> index e07ca7b..9794553 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -95,39 +95,25 @@ extern int get_u16(unsigned short *val, const char *arg, int base)
> return 0;
> }
>
> -static int is_all_slashes(char *path)
> -{
> - while (*path && *path == '/')
> - path++;
> - if (*path)
> - return 0;
> - return 1;
> -}
> -
> extern int mkdir_p(char *dir, mode_t mode)
> {
> - int ret;
> - char *d;
> -
> - if (is_all_slashes(dir))
> - return 0;
> -
> - d = strdup(dir);
> - if (!d)
> - return -1;
> -
> - ret = mkdir_p(dirname(d), mode);
> - free(d);
> - if (ret)
> - return -1;
> -
> - if (!access(dir, F_OK))
> - return 0;
> -
> - if (mkdir(dir, mode)) {
> - SYSERROR("failed to create directory '%s'\n", dir);
> - return -1;
> - }
> + char *tmp = dir;
> + char *orig = dir;
> + char *makeme;
> +
> + do {
> + dir = tmp + strspn(tmp, "/");
> + tmp = dir + strcspn(dir, "/");
> + makeme = strndupa(orig, dir - orig);
strndupa *can* fail and return NULL.
> + if (*makeme) {
> + if (!access(makeme, F_OK))
> + return 0;
did you mean to continue here?
> + if (mkdir(makeme, mode)) {
As people are starting to want to thread, I think it's worth making sure
all mkdirs and creats check for errno=-EEXIST even if they've just
checked with access. Certainly with the cgroup setup a race is possible
when starting two simultaneous containers first time after boot using
the api.
> + SYSERROR("failed to create directory '%s'\n", makeme);
> + return -1;
> + }
> + }
> + } while(tmp != dir);
>
> return 0;
> }
> --
> 1.8.1.4
>
More information about the lxc-devel
mailing list