[Gluster-devel] trusted.glusterfs.location
Ville Tuulos
tuulos at gmail.com
Tue Aug 25 06:12:23 UTC 2009
On Sun, 23 Aug 2009, Anand Avati wrote:
> Can you please submit this patch via git format-patch and
> mutt/git-send-email it to gluster-devel@ ? More comments inline -
I can re-send the patch once I'm sure that it does what it should.
>> I finally managed to get the trusted.glusterfs.location work with 2.0.6. I
>> needed to make some minor modifications to the patch bfb7af7aa316ba, which
>> adds support for trusted.glusterfs.location, to make it work with the latest
>> release.
>>
>> For some reason, getfattr always returned a zero-length value although it
>> recognized the key. I tracked down this problem to dict_set_static_ptr in
>> posix.c. Changing this to dict_set_str seemed to fix the problem, combined
>> with a small change in fuse-bridge.c to drop the zero byte in the end of the
>> value.
>
> I believe that the fuse-bridge.c change alone fixed the nul
> termination problem. Using dict_set_str in this case is dangerous and
> will result in double freeing of the priv->hostname pointer. Please
> see comments further below
I'm not sure about that. It seems that the client receives zero bytes of
the value with the original dict_set_static_ptr(). Of course I don't the
codebase intimately - I just tried to debug this particular problem. See
below for a comment about dict_set_str.
>> A trickier issue is that the trusted.* namespace is only accessible with the
>> CAP_SYS_ADMIN capability in linux. This means that ordinary users can't
>> resolve locations of files as before. Also, we're using OpenVZ containers
>> for virtualization and apparently not even root has the CAP_SYS_ADMIN
>> capability in a virtual machine, so trusted.glusterfs.location can't be
>> accessed in a container at all.
>>
>> Is there some particular reason why you couldn't expose the attribute in the
>> user.* namespace? I patched our gluster to use user.glusterfs.location,
>> which solves both the issue with ordinary users and makes the attribute
>> available to openvz containers.
>
> There is no particular reason. Using user.* should be just as fine.
Great! This would be really helpful.
>> Find below a patch against 2.0.6 that fixes the aforementioned issues. I'd
>> appreciate if you could consider using the user.* namespace in 2.0.7. Also,
>> as I mentioned in an earlier email, it'd be useful to know all locations of
>> the file when cluster/replicate is in use, to let Disco and others utilize
>> replicas in case that the primary copy fails.
>
> This would need some code change in replicate's getxattr call.
> Currently it picks an (arbitrary) subvolume and forwards the xattr
> read call to it. It should be enhanced to forward the
> "user.glusterfs.location" key call to all subvolumes and merge the
> values in a suitable way (comma separated?).
Hmm, is it really an arbitrary subvolume, i.e. not the one that Gluster
actually uses as the primary copy? A comma separated and ordered list
would be perfect for Disco.
>> diff --git a/xlators/mount/fuse/src/fuse-bridge.c
>> b/xlators/mount/fuse/src/fuse-bridge.c
>> index 61fd257..011b280 100644
>> --- a/xlators/mount/fuse/src/fuse-bridge.c
>> +++ b/xlators/mount/fuse/src/fuse-bridge.c
>> @@ -2000,7 +2000,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie,
>> xlator_t *this,
>> /* if callback for getxattr */
>> value_data = dict_get (dict, state->name);
>> if (value_data) {
>> - ret = value_data->len; /* Don't return the
>> value for '\0' */
>> + ret = value_data->len - 1; /* Don't return
>> the value for '\0' */
>
> This is not a good idea since all data being returned is not
> necessarily a null terminated string. You might want to use
> dict_set_static_bin() with appropriate data length (without counting
> the nul).
Right, good point.
>> if (loc->inode && S_ISREG (loc->inode->st_mode) && name &&
>> - (strcmp (name, "trusted.glusterfs.location") == 0)) {
>> - ret = dict_set_static_ptr (dict,
>> - "trusted.glusterfs.location",
>> - priv->hostname);
>> + (strcmp (name, "user.glusterfs.location") == 0)) {
>> + ret = dict_set_str (dict,
>> + "user.glusterfs.location",
>> + priv->hostname);
>
> dict_set_static_str is the right function to use here. For your case
> use dict_set_static_bin() with len as strlen(priv->hostname).
I'm not sure what you mean by dict_set_static_str? At least dict.c in
2.0.6 doesn't have such a function.
I tried to understand how different dict_set_* functions work, and looking
at dict_set_str, it seems to do just
data_t *data = get_new_data ();
data->len = strlen (value) + 1;
data->data = value;
data->is_static = 1;
whereas dict_set_static_bin does
data_t *data = get_new_data ();
data->is_static = 1;
data->len = len;
data->data = value;
To me using dict_set_static_bin(dict, "...", priv->hostname,
strlen(priv->hostname) + 1) seem exactly same as dict_set_str(). I wonder
what you meant by "Using dict_set_str in this case is dangerous and will
result in double freeing of the priv->hostname pointer".
I'm sorry if I've missed something obvious. I'm just trying to understand
the codebase better.
Thanks for your advice again!
Ville
More information about the Gluster-devel
mailing list