--- rpm-4.3.3/lib/fsm.h.magic 2005-08-25 16:44:44.000000000 +0400 +++ rpm-4.3.3/lib/fsm.h 2005-08-25 16:47:02.000000000 +0400 @@ -67,6 +67,7 @@ FSM_STAT = _fs(49), FSM_READLINK= _fs(50), FSM_CHROOT = _fs(51), + FSM_VZRENAME = _fs(55), FSM_NEXT = _fd(65), FSM_EAT = _fd(66), --- rpm-4.3.3/lib/fsm.c.magic 2005-08-25 16:44:44.000000000 +0400 +++ rpm-4.3.3/lib/fsm.c 2005-08-25 16:55:54.000000000 +0400 @@ -42,6 +42,9 @@ int _fsm_threads = 0; /*@=exportheadervar@*/ +extern int rpm_veid; +int VZRename(const char *oldpath, const char *newpath); + /* XXX Failure to remove is not (yet) cause for failure. */ /*@-exportlocal -exportheadervar@*/ /*@unchecked@*/ @@ -1776,12 +1779,24 @@ const char * opath = fsm->opath; fsm->opath = fsm->path; fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix); - rc = fsmNext(fsm, FSM_RENAME); - if (!rc) - rpmMessage(RPMMESS_WARNING, - _("%s saved as %s\n"), - (fsm->opath ? fsm->opath : ""), - (fsm->path ? fsm->path : "")); + if(rpm_veid) + { + rc = fsmNext(fsm, FSM_VZRENAME); + if (!rc) + rpmMessage(RPMMESS_WARNING, + _("%s saved (VZ) as %s\n"), + (fsm->opath ? fsm->opath : ""), + (fsm->path ? fsm->path : "")); + } else + { + rc = fsmNext(fsm, FSM_RENAME); + if (!rc) + rpmMessage(RPMMESS_WARNING, + _("%s saved as %s\n"), + (fsm->opath ? fsm->opath : ""), + (fsm->path ? fsm->path : "")); + } + fsm->path = _free(fsm->path); fsm->opath = opath; } @@ -1913,12 +1928,24 @@ const char * path = fsm->path; fsm->opath = fsmFsPath(fsm, st, NULL, NULL); fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix); - rc = fsmNext(fsm, FSM_RENAME); - if (!rc) { - rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), - (fsm->opath ? fsm->opath : ""), - (fsm->path ? fsm->path : "")); + if(rpm_veid) + { + rc = fsmNext(fsm, FSM_VZRENAME); + if (!rc) { + rpmMessage(RPMMESS_WARNING, _("%s saved (VZ) as %s\n"), + (fsm->opath ? fsm->opath : ""), + (fsm->path ? fsm->path : "")); + } + } else + { + rc = fsmNext(fsm, FSM_RENAME); + if (!rc) { + rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), + (fsm->opath ? fsm->opath : ""), + (fsm->path ? fsm->path : "")); + } } + fsm->path = _free(fsm->path); fsm->path = path; fsm->opath = _free(fsm->opath); @@ -2165,6 +2192,13 @@ fsm->opath, fsm->path, (rc < 0 ? strerror(errno) : "")); if (rc < 0) rc = CPIOERR_RENAME_FAILED; break; + case FSM_VZRENAME: + rc = VZRename(fsm->opath, fsm->path); + if (_fsm_debug && (stage & FSM_SYSCALL)) + rpmMessage(RPMMESS_DEBUG, " %8s (%s, %s) %s\n", cur, + fsm->opath, fsm->path, (rc < 0 ? strerror(errno) : "")); + if (rc < 0) rc = CPIOERR_COPY_FAILED; + break; case FSM_MKDIR: rc = Mkdir(fsm->path, (st->st_mode & 07777)); if (_fsm_debug && (stage & FSM_SYSCALL)) @@ -2504,6 +2538,7 @@ case FSM_UNLINK: return "Unlink"; case FSM_RENAME: return "Rename"; + case FSM_VZRENAME: return "VZRename"; case FSM_MKDIR: return "Mkdir"; case FSM_RMDIR: return "rmdir"; case FSM_LSETFCON: return "lsetfcon"; @@ -2541,3 +2576,74 @@ } /*@noteached@*/ } + +int VZRename(const char *oldpath, const char *newpath) +{ + int res; + void * b1,*b2; + int fd1,fd2; + off_t start; + size_t length,size; + struct stat sb; + + + res = 0; + + fd1 = open(oldpath,O_RDONLY); + if (fd1 < 0) + { +/* fprintf(stderr,"Unable to open %s for Rename!\n",oldpath);*/ + return -1; + } + if(fstat(fd1,&sb)) + { + return -1; + } + size = sb.st_size; + + fd2 = open(newpath,O_CREAT| O_RDWR,0644); + if (fd2 < 0) + { +/* fprintf(stderr,"Unable to open/create %s for Rename!\n",newpath);*/ + close(fd1); + return -1; + } + if(ftruncate(fd2,size)) + { +/* fprintf(stderr,"Unable to truncate %s to %d bytes for Rename!\n",newpath,size);*/ + close(fd1); + return -3; + } + + for(start=0; start < size; start += 0x100000) + { + if(size - start > 0x100000) + length = 0x100000; + else + length = size - start; + b1 = mmap(NULL,length,PROT_READ,MAP_PRIVATE,fd1,start); + if (b1 == MAP_FAILED) + { +/* perror(oldpath);*/ + close(fd1); + close(fd2); + return -2; + } + b2 = mmap(NULL,length,PROT_READ | PROT_WRITE,MAP_SHARED,fd2,start); + if (b2 == MAP_FAILED) + { +/* perror(newpath);*/ + munmap(b1,length); + close(fd1); + close(fd2); + return -2; + } + memcpy(b2,b1,length); + munmap(b1,length); + munmap(b2,length); + } + close(fd1); + close(fd2); + unlink(oldpath); + return res; +}