-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libzfs zpool_find_vdev() overwrites pool config #4312
Comments
That's not good. The problem is with The following tiny patch solves the issue but there may be a cleaner way to do this. diff --git a/lib/libzfs/libzfs_util.c b/lib/libzfs/libzfs_util.c
index fa55fd3..65b04c5 100644
--- a/lib/libzfs/libzfs_util.c
+++ b/lib/libzfs/libzfs_util.c
@@ -1029,16 +1029,18 @@ zfs_strcmp_pathname(char *name, char *cmp, int wholedisk)
int path_len, cmp_len;
char path_name[MAXPATHLEN];
char cmp_name[MAXPATHLEN];
- char *dir;
+ char *dir, *dup;
/* Strip redundant slashes if one exists due to ZPOOL_IMPORT_PATH */
memset(cmp_name, 0, MAXPATHLEN);
- dir = strtok(cmp, "/");
+ dup = strdup(cmp);
+ dir = strtok(dup, "/");
while (dir) {
strcat(cmp_name, "/");
strcat(cmp_name, dir);
dir = strtok(NULL, "/");
}
+ free(dup);
if (name[0] != '/')
return (zfs_strcmp_shortname(name, cmp_name, wholedisk));
It occurs to me this might be causing other subtle problems in the utilities, but it's hard to say. |
Thanks for the rapid response. For me the first vdev find operation was preventing future ones from succeeding. |
No problem, you did all the hard work for me! I've opened #4315 with the proposed fix above to get comment and so we don't loose track of it. |
I've searched and everywhere I look, people say not to use strtok() because it's not thread safe and can't be used in multi-threaded programs. Though there are not a lot of replacements out there. The only thing I've seen is this: http://www.fi.muni.cz/usr/jkucera/tic/tic0226.html which demonstrates how to write a safe replacement that doesn't overwrite the files. But, that's even more lines of code. In other words, I don't think there really is a more elegant way and is the same method on all the help sites. |
@ dracwyrm thanks for checking into strtok(). In general libzfs is not thread safe in that each instance (lib handle or in this case a pool handle) keeps unprotected global state. For example, the error state functions assume a single thread is making calls. |
@dracwyrm sorry I meant to comment on that. You raise a good point but the unfortunate reality is as @don-brady pointed out, the whole thing isn't thread-safe. There's definitely a case to be made for not making it any worse but let's tackle that in another patch. We can convert all the |
When extracting tokens from the string strtok(2) is allowed to modify the passed buffer. Therefore the zfs_strcmp_pathname() function must make a copy of the passed string before passing it to strtok(3). Signed-off-by: Brian Behlendorf <[email protected]> Signed-off-by: Don Brady <[email protected]> Closes #4312
In zfsonlinx, the libzfs
zpool_find_vdev()
function has the side-effect of overwriting the pool config associated with the pool handle. Found while integration zfs_mod.c from illumos.code path of overwrite:
zpool_find_vdev()
grabs config nvlist from pool handle and extracts vdev treevdev_to_nvlist_iter()
with vdev tree, visiting each vdevzfs_strcmp_pathname()
with 'path' string valuestrtok()
on above string and path value is overwrittenan easy way to reproduce is (see actual code below):
stand-alone code that repoduces the problem:
The text was updated successfully, but these errors were encountered: