-
Notifications
You must be signed in to change notification settings - Fork 36
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
Setting an attribute using plfs_setxattr and then getting it using plfs_getxattr #331
Comments
On Thu, Dec 05, 2013 at 12:39:26PM -0800, hadimontakhabi wrote:
did you solve that? the xattr code is pretty simple (see also you can look at the files on the backend. should store chuck |
I've assigned this to David Shrader, whose job assignment includes more PLFS development this year. Thanks for the inside information about the xattrs subdirectory. That will help David to investigate this bug. That said, I don't discourage Hadi from investigating on his own. If he finds a solution, he can let us know. Thanks, From: chuckcranor <notifications@github.commailto:notifications@github.com> On Thu, Dec 05, 2013 at 12:39:26PM -0800, hadimontakhabi wrote:
did you solve that? the xattr code is pretty simple (see also you can look at the files on the backend. should store chuck — |
I haven't figured it out yet, but I will look into it. |
I'm looking in to this now, so I thought I would put down what I have found. I have reproduced the behavior. That is, the number returned for num_hostdirs from plfs_getxattr is different than that set by plfs_setxattr. The value returned by plfs_getxattr seems to be random. Looking in the xattrs directory for the file does have a num_hostdirs file, but it doesn't have anything in it that I can read. What format are the files in xattrs supposed to be? Binary? |
I don't think it is a binary file. |
On Wed, Dec 11, 2013 at 09:27:30AM -0800, hadimontakhabi wrote:
see plfs-core/src/XAttrs.cpp ... the key is stored as the filename chuck simplified setXAttr: plfs_error_t XAttrs::setXAttr(string key, const void* value, size_t len)
} |
No so easy for me to find, but I think I have found the issue. Here is the code that I think is the issue from around line 90 of XAttrs.cpp:
Here, buff and value contain what we just got from a call to Pread. The problem is that xattr doesn't copy the stuff from value; instead it is still pointing to it after the free command. In my debug sessions, as soon as value is freed, the xattr->value goes to something invalid. Since xattr->value is the result we want to pass back up, we pass the wrong thing up. I have tested commenting out the "free(value)" line and everything seems to work. However, I am not sure that removing the free call is what we want. It has been a long time since I coded in C++. Do we need to free value? I mean, do we need to remove just the reference "value" without freeing the memory it is pointing to? Basically, we're allocating memory in or below XAttrs::getXAttr and passing that back up to whatever called it. Is that wise? Would it be better to allocate an XAttr before calling XAttrs::getXAttr and passing that in? |
For this issue, the calling function (Container_fd::getxattr) does delete the XAttr that is passed up to it. I think removing the free call should be sufficient, but I'd like others to weigh in just in case I have missed something. |
If you do that, then the preceding malloc() will leak memory. I think the Someone checked 80+ lines into XAttr.cpp. :( John On Wed, Dec 11, 2013 at 5:06 PM, David notifications@github.com wrote:
|
On Wed, Dec 11, 2013 at 04:25:18PM -0800, John Bent wrote:
that seems reasonable. class XAttr should be tracking the length chuck |
I've been talking with David B about this issue, and we have implemented keeping track of the length inside the XAttr structure. However, we have discovered that we have been violating the standard convention for getxattr. From the man page for getxattr:
Right now, if we pass in a len of 0 to our plfs_getxattr, we get bad things (memcpy of 0). In other words, we are trusting the user to keep track of the size of the extended attribute that we are storing. If they give too big of a length, we read off the extended attribute's file (generates an error); too small and we return a truncated attribute (not helpful). We need a way to let the user know how big of a buffer they need. POSIX getxattr does this via the return value, which we cannot emulate with the new plfs error/return types. We could use another argument to take care of this, but this changes the external interface. This type of change doesn't change the MPI patch as it doesn't use extended attributes. If we don't want to trust the user to always know how big our extended attributes are, we need to implement a solution to finding out how big an extended attribute is from the file that we drop in the xattrs directory (there is no sense of the XAttr class when plfs_getxattr is called). |
On Thu, Dec 12, 2013 at 08:32:34AM -0800, David wrote:
seems like we've already broken the POSIX thing with the plfs_error_t chuck |
Nice catch. Agreed.
I'd say let's add this extra argument and change the external interface. We'd have to do that anyway to let the user specify the size of the void* when they set it. John |
We were freeing memory before returning it far enough to get to the user. This is in reference to Issue plfs#331. Now, the value of an xattr is stored within the XAttr class instead of pointing to what the user gave us. The length of the xattr is now also stored in the XAttr class for book-keeping purposes. The XAttr destructor now frees properly.
Please take a look at the pull request and let me know if there are any objections. It only fixes the return value of plfs_getxattr; it doesn't deal with the issue that we found with plfs_getxattr and the length of the extended attribute. I'm going to open another issue for that and close this one when we merge in a fix. |
On Thu, Dec 12, 2013 at 09:35:36AM -0800, David wrote:
seems about right, but is it doing a double copy of the data? chuck |
Yep, it is. I've made one more change that I'll add to the merge request. |
Follow-up commit for issue plfs#331.
This should now be fixed in master. I just merged Pull Request #334. |
Here is what I have now.
I am opening a file, writing something to it, then setting an attribute (num_hostdir), and then I try to get the same attribute.
The value that I get is different than what I set.
Any thoughts on that?
int main()
{
Plfs_fd *pfd = NULL;
char wpath[100];
char buf[] = "somrthing to write";
int offset = 0;
ssize_t bytes;
char filename[] = "filename.txt";
int flags;
plfs_error_t plfs_ret;
int value = 10;
size_t len = sizeof(int);
char key[] = "num_hostdirs";
getcwd(wpath, sizeof(wpath));
sprintf(wpath,"%s/%s",wpath,filename);
fprintf(stdout, "wpath: %s\n", wpath);
plfs_open( &pfd, wpath, O_CREAT | O_WRONLY | O_RDONLY, 0, 0666, NULL );
plfs_write( pfd, buf, sizeof(buf), offset, 0, &bytes );
plfs_ret = plfs_setxattr( pfd, &value, key, len );
if (plfs_ret != PLFS_SUCCESS) {
printf("ERROR in plf_setxattr:\n%s\n", strplfserr(plfs_ret));
}
else {
printf("after setting: num_hostdir = %d\n",value);
}
plfs_ret = plfs_getxattr( pfd, &value, key, len );
if (plfs_ret != PLFS_SUCCESS) {
printf("ERROR in plf_getxattr:\n%s\n", strplfserr(plfs_ret));
}
else {
printf("after getting: num_hostdir = %d\n",value);
}
plfs_ret = plfs_close(pfd, 0, 0, O_CREAT | O_WRONLY | O_RDONLY ,NULL, &flags);
return 0;
}
The text was updated successfully, but these errors were encountered: