diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/common-utils.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/compat.c | 244 | ||||
| -rw-r--r-- | libglusterfs/src/compat.h | 8 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
| -rw-r--r-- | libglusterfs/src/inode.c | 2 | ||||
| -rw-r--r-- | libglusterfs/src/inode.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/syscall.c | 6 | 
7 files changed, 247 insertions, 18 deletions
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 0cb53d1bf..0d93e5bee 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -144,6 +144,8 @@ extern char *gf_mgmt_list[GF_MGMT_MAXVALUE];          } while (0);  #endif +#define GF_HIDDEN_PATH ".glusterfs" +  static inline void  iov_free (struct iovec *vector, int count)  { diff --git a/libglusterfs/src/compat.c b/libglusterfs/src/compat.c index 210221631..914fb2006 100644 --- a/libglusterfs/src/compat.c +++ b/libglusterfs/src/compat.c @@ -35,9 +35,10 @@  #include "compat.h"  #include "common-utils.h" +#include "iatt.h" +#include "inode.h"  #ifdef GF_SOLARIS_HOST_OS -  int   solaris_fsetxattr(int fd,   		  const char* key,  @@ -97,6 +98,125 @@ solaris_fgetxattr(int fd,  	return ret;  } +/* Solaris does not support xattr for symlinks and dev files. Since gfid and +   other trusted attributes are stored as xattrs, we need to provide support for +   them. A mapped regular file is stored in the /.glusterfs_xattr_inode of the export dir. +   All xattr ops related to the special files are redirected to this map file. +*/ + +int +make_export_path (const char *real_path, char **path) +{ +        int     ret = -1; +        char   *tmp = NULL; +        char   *export_path = NULL; +        char   *dup = NULL; +        char   *ptr = NULL; +        char   *freeptr = NULL; +        uuid_t  gfid = {0, }; +         +        export_path = GF_CALLOC (1, sizeof (char) * PATH_MAX, 0); +        if (!export_path) +                goto out; + +        dup = gf_strdup (real_path); +        if (!dup) +                goto out; + +        freeptr = dup; +        ret = solaris_getxattr ("/", GFID_XATTR_KEY, gfid, 16); +        /* Return value of getxattr */ +        if (ret == 16) { +                if (!__is_root_gfid (gfid)){ +                        strcat (export_path, "/"); +                        ret = 0; +                        goto done; +                } +        } +         +        do { +                ptr = strtok_r (dup, "/", &tmp); +                if (!ptr) +                        break; +                strcat (export_path, dup); +                ret = solaris_getxattr (export_path, GFID_XATTR_KEY, gfid, 16); +                if (ret == 16) { +                        if (!__is_root_gfid (gfid)) { +                                ret = 0; +                                goto done; +                        } +                }                                 +                strcat (export_path, "/"); +                dup = tmp; +        } while (ptr); + +        goto out; + +done: +        if (!ret) { +                *path = export_path; +        } +out: +        if (freeptr) +                GF_FREE (freeptr); +        if (ret && export_path) +                GF_FREE (export_path); + +        return ret; +} +int +solaris_xattr_resolve_path (const char *real_path, char **path) +{ +        int                    ret  = -1; +        char                   *export_path = NULL; +        char                   xattr_path[PATH_MAX] = {0, }; +        struct stat            lstatbuf = {0, }; +        struct iatt            stbuf = {0, }; +        struct stat            statbuf = {0, }; + +        ret = lstat (real_path, &lstatbuf); +        if (ret != 0 ) +                return ret; +        iatt_from_stat (&stbuf, &lstatbuf); +        if (IA_ISREG(stbuf.ia_type) || IA_ISDIR(stbuf.ia_type)) +                return -1; + +        ret = make_export_path (real_path, &export_path); +        if (!ret && export_path) { +                strcat (export_path, "/"GF_SOLARIS_XATTR_DIR); +                if (lstat (export_path, &statbuf)) { +                        ret = mkdir (export_path, 0777); +                        if (ret && (errno != EEXIST)) { +                        	gf_log ("", GF_LOG_DEBUG, "mkdir failed,"  +                                        " errno: %d", errno); +                        	goto out; +                        } +                } +                 +                snprintf(xattr_path, PATH_MAX, "%s%s%lu", export_path, +                        "/", stbuf.ia_ino); + +		ret = lstat (xattr_path, &statbuf); + +		if (ret) { +			ret = mknod (xattr_path, S_IFREG|O_WRONLY, 0); +			if (ret && (errno != EEXIST)) { +				gf_log ("", GF_LOG_WARNING,"Failed to create " +					"mapped file %s, error %d", xattr_path, +                                         errno); +				goto out; +			}					 +		} +                *path = gf_strdup (xattr_path); +        } +out: +        if (export_path) +                GF_FREE (export_path); +        if (*path) +                return 0; +        else +                return -1; +}  int   solaris_setxattr(const char *path,  @@ -107,21 +227,30 @@ solaris_setxattr(const char *path,  {  	int attrfd = -1;  	int ret = 0; -	 -	attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777); +        char *mapped_path = NULL; + +        ret = solaris_xattr_resolve_path (path, &mapped_path); +        if (!ret) { +                attrfd = attropen (mapped_path,  key, flags|O_CREAT|O_WRONLY, +                                   0777); +        } else { +                attrfd = attropen (path, key, flags|O_CREAT|O_WRONLY, 0777); +        }  	if (attrfd >= 0) {  		ftruncate (attrfd, 0);  		ret = write (attrfd, value, size);  		close (attrfd); +                ret = 0;  	} else {  		if (errno != ENOENT)  			gf_log ("libglusterfs", GF_LOG_ERROR,   				"Couldn't set extended attribute for %s (%d)",   				path, errno); -		return -1; +		ret = -1;  	} -	 -	return 0; +        if (mapped_path) +                GF_FREE (mapped_path);	 +	return ret;  } @@ -135,8 +264,15 @@ solaris_listxattr(const char *path,  	DIR *dirptr = NULL;  	struct dirent *dent = NULL;  	int newfd = -1; -	 -	attrdirfd = attropen (path, ".", O_RDONLY, 0); +        char *mapped_path = NULL; +        int ret = -1; + +        ret = solaris_xattr_resolve_path (path, &mapped_path); +        if (!ret) { +                attrdirfd = attropen (mapped_path, ".", O_RDONLY, 0); +        } else {	 +                attrdirfd = attropen (path, ".", O_RDONLY, 0); +        }  	if (attrdirfd >= 0) {  		newfd = dup(attrdirfd);  		dirptr = fdopendir(newfd); @@ -167,14 +303,19 @@ solaris_listxattr(const char *path,  			if (closedir(dirptr) == -1) {  				close (attrdirfd); -				return -1; +				len = -1; +                                goto out;  			}  		} else {  			close (attrdirfd); -			return -1; +			len = -1; +                        goto out;  		}  		close (attrdirfd);  	} +out: +        if (mapped_path) +                GF_FREE (mapped_path);  	return len;  } @@ -238,17 +379,28 @@ solaris_removexattr(const char *path,  		    const char* key)  {  	int ret = -1; -	int attrfd = attropen (path, ".", O_RDONLY, 0); +        int attrfd = -1; +        char *mapped_path = NULL; + +        ret = solaris_xattr_resolve_path (path, &mapped_path); +        if (!ret) { +                attrfd = attropen (mapped_path, ".", O_RDONLY, 0); +        } else { +                attrfd = attropen (path, ".", O_RDONLY, 0); +        }  	if (attrfd >= 0) {  		ret = unlinkat (attrfd, key, 0);  		close (attrfd);  	} else {  		if (errno == ENOENT)  			errno = ENODATA; -		return -1; +		ret = -1;  	} -	 -	return ret; + +        if (mapped_path) +                GF_FREE (mapped_path); + +        return ret;  }  int  @@ -259,8 +411,15 @@ solaris_getxattr(const char *path,  {  	int attrfd = -1;  	int ret = 0; -	 -	attrfd = attropen (path, key, O_RDONLY, 0); +        char *mapped_path = NULL; + +        ret = solaris_xattr_resolve_path (path, &mapped_path); +        if (!ret) { +                attrfd = attropen (mapped_path, key, O_RDONLY, 0); +        } else {  +                attrfd = attropen (path, key, O_RDONLY, 0); +        } +  	if (attrfd >= 0) {  		if (size == 0) {  			struct stat buf; @@ -277,8 +436,10 @@ solaris_getxattr(const char *path,  			gf_log ("libglusterfs", GF_LOG_DEBUG,   				"Couldn't read extended attribute for the file %s (%d)",   				path, errno); -		return -1; +		ret = -1;  	} +        if (mapped_path) +                GF_FREE (mapped_path);  	return ret;  } @@ -326,6 +487,55 @@ asprintf (char **buf, const char *fmt, ...)    return status;    } +int solaris_unlink (const char *path) +{ +        char *mapped_path = NULL; +        struct stat	stbuf = {0, }; +        int ret = -1; + +        ret = solaris_xattr_resolve_path (path, &mapped_path); +	 + +        if (!ret && mapped_path) { +		if (lstat(path, &stbuf)) { +			gf_log ("",GF_LOG_WARNING, "Stat failed on mapped" +				" file %s with error %d", mapped_path, errno); +			goto out; +		} +                if (stbuf.st_nlink == 1) { +			 if(remove (mapped_path)) +                        	gf_log ("", GF_LOG_WARNING, "Failed to remove mapped " +					"file %s. Errno %d", mapped_path, errno); +		} + +	} + +out: +	if (mapped_path) +		GF_FREE (mapped_path); + +	return  unlink (path); +} + +int +solaris_rename (const char *old_path, const char *new_path) +{ +        char *mapped_path = NULL; +        int ret = -1; + +        ret = solaris_xattr_resolve_path (new_path, &mapped_path); + + +        if (!ret && mapped_path) { +                if (!remove (mapped_path)) +                        gf_log ("", GF_LOG_WARNING, "Failed to remove mapped " +                                "file %s. Errno %d", mapped_path, errno); +        	GF_FREE (mapped_path); +	} + +        return rename(old_path, new_path); + +}  #endif /* GF_SOLARIS_HOST_OS */  #ifndef HAVE_STRNLEN diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index 690b4f9e6..cae3342ef 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -280,6 +280,14 @@ int solaris_fsetxattr(int fd, const char* key, const char *value,                        size_t size, int flags);  int solaris_flistxattr(int fd, char *list, size_t size); +int solaris_rename (const char *oldpath, const char *newpath); + +int solaris_unlink (const char *pathname); + +#define GF_SOLARIS_XATTR_DIR ".glusterfs_xattr_inode" + +int solaris_xattr_resolve_path (const char *real_path, char **path); +  #endif /* GF_SOLARIS_HOST_OS */  #ifndef HAVE_ARGP diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index aaf00c311..6e23c283a 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -70,6 +70,7 @@  #define GF_XATTR_PATHINFO_KEY   "trusted.glusterfs.pathinfo"  #define GF_XATTR_LINKINFO_KEY   "trusted.distribute.linkinfo" +#define GFID_XATTR_KEY "trusted.gfid"  #define ZR_FILE_CONTENT_STR     "glusterfs.file."  #define ZR_FILE_CONTENT_STRLEN 15 diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index 919f82143..e193d7824 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -636,7 +636,7 @@ inode_get (inode_table_t *table, ino_t ino, uint64_t gen)  } -static int +int  __is_root_gfid (uuid_t gfid)  {          uuid_t  root; diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h index 15a4f98f7..375ff3ee4 100644 --- a/libglusterfs/src/inode.h +++ b/libglusterfs/src/inode.h @@ -182,4 +182,6 @@ int  inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,                  uint64_t *value2); +int +__is_root_gfid (uuid_t gfid);  #endif /* _INODE_H */ diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index c0855f1d1..6750b313d 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -95,6 +95,9 @@ sys_mkdir (const char *pathname, mode_t mode)  int   sys_unlink (const char *pathname)  { +#ifdef GF_SOLARIS_HOST_OS +        return solaris_unlink (pathname); +#endif          return unlink (pathname);  } @@ -116,6 +119,9 @@ sys_symlink (const char *oldpath, const char *newpath)  int  sys_rename (const char *oldpath, const char *newpath)  { +#ifdef GF_SOLARIS_HOST_OS +        return solaris_rename (oldpath, newpath); +#endif          return rename (oldpath, newpath);  }  | 
