Enrico Cavalli
2009-Jul-27 07:30 UTC
supporting --fake-super on opensolaris (zfs) destination
Hello everybody. I wrote a small patch in order to support what I think is an absolutely needed feature in order to make rsync-based backups retaining complete ownership permission when writing to an opensolaris machine using --fake-super. My goal is making backups of linux boxes to opensolaris/zfs. In order to make it work just do patch -p1 < patch_file.txt inside rsync source tree. and set #define SUPPORT_XATTRS 1 in config.h I tested the patch with rsync 3.0.6 and the last git commit. Disclaimer: 1) I'm not a filesystem programmer 2) the patch is surely full of nasty bugs and could be insecure/break your systems. etc etc. 3) even if you define SUPPORT_XATTRS, rsync -X won't work TODO - write true xattr support for opensolaris - wrap this up with configure to recognize opensolaris and define HAVE_SOLARIS_XATTRS for instance - support linux XATTRS on symlinks on the solaris side: for instance if I have /usr/bin/xyz -> /usr/bin/abc I could write the extended attributes of symlink xyz inside a directory named xyz rooted at the parent /usr/bin I hope my little effort would encourage some true system programmers to write somthing more general and useful. Please do not laugh reading my code: see disclaimer :) -- Enrico Cavalli CILEA - via R. Sanzio 4, 20090 - Segrate (MI), Italy phone: +39 02 26995.1 - fax: +39 02 2135520 - skype: enricocavalli GTalk/Jabber/iChat: enrico.cavalli at gmail.com PGP Fingerprint: 3762 7B1B 743E 029C 8F94 8ADE BC4B 43A7 0485 30E5 -------------- next part -------------- diff --git a/lib/sysxattrs.c b/lib/sysxattrs.c index 12e456e..8655760 100644 --- a/lib/sysxattrs.c +++ b/lib/sysxattrs.c @@ -128,7 +128,155 @@ ssize_t sys_llistxattr(const char *path, char *list, size_t size) #else -#error You need to create xattr compatibility functions. +ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size) +{ + + + int attrfd; + size_t bufpos,r; + STRUCT_STAT fst; + + do_lstat(path,&fst); + if(S_ISLNK(fst.st_mode)) { + errno=EPERM; + return(-1); + } + + attrfd = attropen(path, name, O_RDONLY); + + if (attrfd<0) { + errno = ENOATTR; + return -1; + } + + + for(bufpos=0;bufpos<size;) { + r=read(attrfd,value+bufpos,512); + if (r==0) break; + if(r<0) { + return -errno; + } + bufpos+=r; + } +close(attrfd); +return (bufpos); + +} + +ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size) +{ + int attrfd; + size_t bufpos,r; + + attrfd=openat(filedes,name,O_RDONLY); + if (attrfd<0) { + errno = ENOATTR; + return -1; + } + + + for(bufpos=0;bufpos<size;) { + r=read(attrfd,value+bufpos,512); + if (r==0) break; + + if(r<0) { + return -errno; + } + bufpos+=r; + } + + +close(attrfd); +return (bufpos); + +} + +int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size) +{ + int attrfd; + size_t bufpos,w; + + STRUCT_STAT fst; + + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + + do_lstat(path,&fst); + + if(S_ISLNK(fst.st_mode)) { + errno=EPERM; + return(-1); + } + + attrfd = attropen(path, name, AT_SYMLINK_NOFOLLOW|O_CREAT|O_RDWR,mode); + + if(attrfd>0) { + + for(bufpos=0;bufpos<size;) { + w = write(attrfd, value+bufpos, size); + if(w<0) return -errno; + bufpos+=w; + + } + close(attrfd); + return (bufpos); +} +return 0; +} + +int sys_lremovexattr(const char *path, const char *name) +{ + int attrdirfd; + int error; + STRUCT_STAT fst; + + do_lstat(path,&fst); + + if(S_ISLNK(fst.st_mode)) { + errno=EPERM; + return(-1); + } + + attrdirfd = attropen(path, ".", O_RDONLY); + + error = unlinkat(attrdirfd,name,0); + + close (attrdirfd); + return error; +} + +ssize_t sys_llistxattr(const char *path, char *list, size_t size) +{ + int attrdirfd; + DIR *dirp; + struct dirent *dp; + int len=0; + + attrdirfd = attropen(path, ".", O_RDONLY); + + if (!attrdirfd) { + errno=ENOTSUP; + return -1; + } + + dirp = fdopendir(attrdirfd); + while ((dp = readdir(dirp))) { + if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0) || + (strcmp(dp->d_name, "SUNWattr_ro") == 0) || (strcmp(dp->d_name, "SUNWattr_rw") == 0)) + continue; + + sprintf(list,dp->d_name); + len=len+strlen(dp->d_name); + list+=strlen(dp->d_name); + list[len]='\0'; + list+=1; + + } + + close(attrdirfd); + closedir(dirp); + return(len); + +} #endif
Wayne Davison
2009-Aug-04 14:07 UTC
supporting --fake-super on opensolaris (zfs) destination
On Mon, Jul 27, 2009 at 07:30:48AM +0000, Enrico Cavalli wrote:> I wrote a small patch in order to support what I think > is an absolutely needed feature in order to make rsync-based backups > retaining complete ownership permission when writing to an opensolaris > machine using --fake-super.Thanks for the preliminary Solaris xattr-support code. I've cleaned it up a bit, and will be checking it into the git repository soon. Let us know how things progress towards full -X support. ..wayne..