-
Notifications
You must be signed in to change notification settings - Fork 369
mkdir -p $runstatedir at run time, not install time #1227
Conversation
81d5133 to
3889f2c
Compare
|
v1b changes:
|
3889f2c to
b2e61d0
Compare
|
v2 changes:
Now it's lightly tested, but only lightly. |
b2e61d0 to
c552be7
Compare
|
v3 changes:
|
|
IIRC the initial intention was to create the_ full_ paths, but there was some reason not to... can't remember where that discussion took place... |
Yup. IIRC, we checked that other programs behaved like mkdir -p too, so there's prior art.
Yeah, that was @thresheek . I don't remember where we talked about it, but I remember what, +/-. He was concerned about mkdir -p being too much, and keeping it simpler if not necessary, to reduce chances of doing something wrong. Well, I'd say we need it, so unless he has stronger reasons to avoid it, I'd go for it. I CCed him, in case he wants to speak. |
| ret = NXT_OK; | ||
|
|
||
| ptr = strrchr(dir, '/'); | ||
| if (nxt_slow_path(ptr == NULL || ptr == dir)) { | ||
| if (ptr == dir || nxt_slow_path(ptr == NULL)) { | ||
| goto out_free; | ||
| } | ||
|
|
||
| *ptr = '\0'; | ||
| if (strcmp(dir, (const char *) path) != 0) | ||
| { | ||
| ret = nxt_fs_mkdir_parent((const u_char *) dir, mode); | ||
| if (nxt_slow_path(ret == NXT_ERROR)) { | ||
| goto out_free; | ||
| } | ||
| } | ||
|
|
||
| ret = nxt_fs_mkdir((const u_char *) dir, mode); | ||
| if (ret == NXT_ERROR && errno == EEXIST) { | ||
| ret = NXT_OK; | ||
| } | ||
|
|
||
| out_free: | ||
| nxt_free(dir); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't you just create 'mkdir -p'?
Maybe the function should be renamed more appropriately (assuming it doesn't need to be retained in its original form)
Also not terribly fond of the recursion... or if some nutter tries to create /a/b/c/d/e/f/g/h/i/j/..., but I can probably live with it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I thought of looping, but since this is something we run just twice, and only at program startup, I guess it's simpler to recurse.
Regarding the name... I thought originally of naming it _parents instead of _parent. However, I thought _parents might be confusing, as it could lead to think that it's equivalent to mkdir -p, while it's equivalent to mkdir -p $(dirname ...). Now that I write this, the obvious name comes to my head as nxt_fs_mkdir_dirname_parents(). Does that sound good to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe _mkdir_parents_dirname ...
src/nxt_fs.c
Outdated
|
|
||
| ptr = strrchr(dir, '/'); | ||
| if (nxt_slow_path(ptr == NULL)) { | ||
| if (nxt_slow_path(ptr == NULL || ptr == dir)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean if someone tried to create the socket or whatever in the root directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. That's unlikely. However, it's necessary for using recursion, since at some point it'll arrive at the parent-most dir, which is of course /usr, and when trying to create its dirname, it'll try /.
This refactor isn't very appealing alone, but it prepares the code for the following commits. Link: <nginx#742> Cc: Andrew Clayton <a.clayton@nginx.com> Cc: Liam Crilly <liam@nginx.com> Cc: Konstantin Pavlov <thresh@nginx.com> Cc: Andy Postnikov <apostnikov@gmail.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
The previous code attempted to mkdir(""), that is an empty string.
Since "/" necessarily exists, just goto out_free.
Link: <nginx#742>
Cc: Andrew Clayton <a.clayton@nginx.com>
Cc: Liam Crilly <liam@nginx.com>
Cc: Konstantin Pavlov <thresh@nginx.com>
Cc: Andy Postnikov <apostnikov@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Build systems should not attempt to create $runstatedir (or anything under it). Doing so causes warnings in packaging systems, such as in Alpine Linux, as reported by Andy. But unitd(8) can be configured to be installed under /opt, or other trees, where no directories exist before hand. Expecting that the user creates the entire directory trees that unit will need is a bit unreasonable. Instead, we can just create any directories that we need, with all their parents. Fixes: 57fc920 ("Socket: Created control socket & pid file directories.") Link: <nginx#742> Reported-by: Andy Postnikov <apostnikov@gmail.com> Cc: Andrew Clayton <a.clayton@nginx.com> Cc: Liam Crilly <liam@nginx.com> Cc: Konstantin Pavlov <thresh@nginx.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
This directory should exist already in the system, and if not, it should
(and will) be created at run time, not at install time.
It triggered a warning in Alpine Linux's packaging system:
ERROR: unit*: Packages must not put anything under /var/run
Fixes: 5a37171 ("Added default values for pathnames.")
Fixes: 57fc920 ("Socket: Created control socket & pid file directories.")
Closes: <nginx#742>
Reported-by: Andy Postnikov <apostnikov@gmail.com>
Cc: Andrew Clayton <a.clayton@nginx.com>
Cc: Liam Crilly <liam@nginx.com>
Cc: Konstantin Pavlov <thresh@nginx.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
c552be7 to
bb26587
Compare
|
v4 changes:
|
Now that I see, there's nxt_fs_mkdir_all(). I guess it's |
However, I see that function asserts that How much is that assertion necessary for the code that uses this function? Can we just remove it? |
|
Why can't we just use We basically just want to do Which I'm sure is what I would have done in the first place, except we didn't for $reason, and I had to create |
I'm adapting it to be able to use it. Out-of-the-box, it has an assertion that makes me suspect it won't please @lcrilly , who runs unitd(8) with a relative $prefix. However, I'm trying to adapt the function to be able to use it.
Actually, mkdir -p $(dirname ...), but yeah, mostly.
Yup. We were almost going to do that, IIRC, when @thresheek suggested not doing so. Out of caution, we didn't. :)
I wish I had suggested calling that _dirname instead of _parent back then. :) (And call the other one _parents instead of _all.) |
|
I think I'm still missing something, why doesn't It works for the cgroups and isolation/rootfs cases where they need to create full directory paths... In src/nxt_isolation.c::nxt_isolation_prepare_rootfs() (src/nxt_isolation.c:783: ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO);) ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO); which for example does |
|
I mean shouldn't you bascially just be able to replace calls to |
We don't want to mkdir the last path-name segment. The last path-name segment is the socket or the pid file. |
Yes, I should be able to do that (to replace the recursion). In fact, that's what I want to do, now that we remember it exists. :-) We still need the wrapper call to get the dirname. |
Oh, right, bugger... Hmm, I'm not convinced trying to mould I would probably just create a simple helper function that uses |
|
But maybe we should wait for further feedback if this is even the way we should go... |
That's my plan. I'm going to drop this patch, and rewrite it to wrap nxt_fs_mkdir_all() in a new function. Which is why I'm first doing some refactors to better understand that code. |
|
If we were to allow relative paths, you'd need to be careful what the current working directory is before hand... I suppose that's sort of true just as it stands now, though this perhaps works through happenstance more than anything... $ pwd
/tmp/unit
$ ls -ld build
ls: cannot access 'build': No such file or directory
$ ./configure --prefix=./build/
$ make -j
...
$ strace -f -e mkdirat,mkdir ./build/sbin/unitd --no-daemon
mkdir("./build//var/lib/unit/certs/", 0700) = 0
mkdir("./build//var/lib/unit/scripts/", 0700) = 0
mkdir("./build//var/run/unit", 0755) = -1 EEXIST (File exists)
mkdir("./build//var/run/unit", 0755) = -1 EEXIST (File exists)
$ cd ..
$ pwd
/tmp
$ strace -f -e mkdirat,mkdir ./unit/build/sbin/unitd --no-daemon
mkdir("./build//var/lib/unit/certs/", 0700) = -1 ENOENT (No such file or directory)
mkdir("./build//var/lib/unit/scripts/", 0700) = -1 ENOENT (No such file or directory)
mkdir("./build//var/run/unit", 0755) = -1 ENOENT (No such file or directory)But it is a use case we should keep working... |
|
I'm closing, in favour of #1235. |
@lcrilly and I worked on making that work. It's a bit brittle, in that you must run unitd(8) from the right working directory, but it works. That's just for running from the source repository, when in a edit-compile-test loop, without having to install (I do install under /opt for those things, but Liam prefers running from there directly.) So, users of this feature should know what they're doing.
|
Not tested. I just built it.
Closes: #742
Fixes: 5a37171 ("Added default values for pathnames.")
Fixes: 57fc920 ("Socket: Created control socket & pid file directories.")
Reported-by: @andypost
Cc: @ac000
Cc: @thresheek
Cc: @lcrilly