Example #1
0
void
UserProc::delete_files()
{
	do_unlink( cur_ckpt );

	if (core_name != NULL) {
		do_unlink( core_name );
	}

	dprintf( D_ALWAYS, "Removing directory \"%s\"\n", local_dir );
	if (privsep_enabled()) {
		// again, the PrivSep Switchboard expects a full path for
		// the "remove dir" operation
		//
		MyString local_dir_path;
		local_dir_path.formatstr("%s/%s", Execute, local_dir);
		if (!privsep_remove_dir(local_dir_path.Value())) {
			dprintf(D_ALWAYS,
			        "privsep_remove_dir failed to remove %s\n",
			        local_dir_path.Value());
		}
	}
	else {
		if( rmdir(local_dir) < 0 ) {
			dprintf( D_ALWAYS,
				"Can't remove directory \"%s\" - errno = %d\n",
			        local_dir,
			        errno);
		}
	}
}
Example #2
0
/*
 * Process a control file.
 */
static void
process(char *file)
{
	FILE *cfp = NULL;
	int fd;

	if (!chk(file))
		return;
	PRIV_START;
	fd = safe_open(file, O_RDONLY|O_NOFOLLOW, 0);
	PRIV_END;
	if (fd < 0 || (cfp = fdopen(fd, "r")) == NULL) {
		if (fd >= 0)
			close(fd);
		fatal("cannot open %s", file);
	}
	while (get_line(cfp)) {
		switch (line[0]) {
		case 'U':  /* unlink associated files */
			if (strchr(line+1, '/') || strncmp(line+1, "df", 2))
				break;
			do_unlink(line+1);
		}
	}
	(void)fclose(cfp);
	do_unlink(file);
}
Example #3
0
/* finish off a file transfer, renaming the file and setting the permissions
   and ownership */
void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
{
	if (make_backups && !make_backup(fname))
		return;

	/* move tmp file over real file */
	if (robust_rename(fnametmp,fname) != 0) {
		if (errno == EXDEV) {
			/* rename failed on cross-filesystem link.  
			   Copy the file instead. */
			if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
				rprintf(FERROR,"copy %s -> %s : %s\n",
					fnametmp,fname,strerror(errno));
			} else {
				set_perms(fname,file,NULL,0);
			}
		} else {
			rprintf(FERROR,"rename %s -> %s : %s\n",
				fnametmp,fname,strerror(errno));
		}
		do_unlink(fnametmp);
	} else {
		set_perms(fname,file,NULL,0);
	}
}
Example #4
0
/* simple backup creates a backup with a suffix in the same directory */
static int make_simple_backup(const char *fname)
{
	int rename_errno;
	const char *fnamebak = get_backup_name(fname);

	if (!fnamebak)
		return 0;

	while (1) {
		if (do_rename(fname, fnamebak) == 0) {
			if (verbose > 1) {
				rprintf(FINFO, "backed up %s to %s\n",
					fname, fnamebak);
			}
			break;
		}
		/* cygwin (at least version b19) reports EINVAL */
		if (errno == ENOENT || errno == EINVAL)
			break;

		rename_errno = errno;
		if (errno == EISDIR && do_rmdir(fnamebak) == 0)
			continue;
		if (errno == ENOTDIR && do_unlink(fnamebak) == 0)
			continue;

		rsyserr(FERROR, rename_errno, "rename %s to backup %s",
			fname, fnamebak);
		errno = rename_errno;
		return 0;
	}

	return 1;
}
Example #5
0
File: util.c Project: empeg/rsync
/* Returns 0 on successful rename, 1 if we successfully copied the file
 * across filesystems, -2 if copy_file() failed, and -1 on other errors.
 * If partialptr is not NULL and we need to do a copy, copy the file into
 * the active partial-dir instead of over the destination file. */
int robust_rename(const char *from, const char *to, const char *partialptr,
		  int mode)
{
	int tries = 4;

	while (tries--) {
		if (do_rename(from, to) == 0)
			return 0;

		switch (errno) {
#ifdef ETXTBSY
		case ETXTBSY:
			if (robust_unlink(to) != 0) {
				errno = ETXTBSY;
				return -1;
			}
			errno = ETXTBSY;
			break;
#endif
		case EXDEV:
			if (partialptr) {
				if (!handle_partial_dir(partialptr,PDIR_CREATE))
					return -2;
				to = partialptr;
			}
			if (copy_file(from, to, -1, mode) != 0)
				return -2;
			do_unlink(from);
			return 1;
		default:
			return -1;
		}
	}
	return -1;
}
Example #6
0
/*
 * Cnf2Msg - convert reply ".cnf" file into ".msg" file for export.
 *
 */
atp_BOOL_T
Cnf2Msg(const char *filemsg)
{
    atp_BOOL_T mrep = FALSE;

    /* Open MsgFile and IdxFile */
    if (OpenRepFile(pack_them)) {
        if ((RepMsg = fopen(filemsg, "wb")) == NULL) {
            /* "unable to open file" */
            fprintf(stderr, "%s %s\n", txt[51], filemsg);
            perror("Does 'workpath' specified in atprc exist? ");
        } else {
            FirstHeader();
            /* copy .cnf to messpath */
            rewind(MsgFile);
            mrep = DoRep(filemsg);
            fclose(RepMsg);
            if (!mrep)
                do_unlink(filemsg);
        }
        /* close message path */
        fclose(MsgFile);
        fclose(IdxFile);
    }
    return mrep;
}
Example #7
0
/* Unlink @subject from the WIM image.
 *
 * This is the journaled version, so it can be rolled back.  */
static int
journaled_unlink(struct update_command_journal *j, struct wim_dentry *subject)
{
	struct wim_dentry *parent;
	struct update_primitive prim;
	int ret;

	if (dentry_is_root(subject))
		parent = NULL;
	else
		parent = subject->d_parent;

	prim.type = UNLINK_DENTRY;
	prim.link.subject = subject;
	prim.link.parent = parent;

	ret = record_update_primitive(j, prim);
	if (ret)
		return ret;

	do_unlink(subject, parent, j->root_p);

	list_add(&subject->tmp_list, &j->orphans);
	subject->is_orphan = 1;
	return 0;
}
Example #8
0
File: util.c Project: empeg/rsync
/**
 * Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
 * rename to <path>/.rsyncNNN instead.
 *
 * Note that successive rsync runs will shuffle the filenames around a
 * bit as long as the file is still busy; this is because this function
 * does not know if the unlink call is due to a new file coming in, or
 * --delete trying to remove old .rsyncNNN files, hence it renames it
 * each time.
 **/
int robust_unlink(const char *fname)
{
#ifndef ETXTBSY
	return do_unlink(fname);
#else
	static int counter = 1;
	int rc, pos, start;
	char path[MAXPATHLEN];

	rc = do_unlink(fname);
	if (rc == 0 || errno != ETXTBSY)
		return rc;

	if ((pos = strlcpy(path, fname, MAXPATHLEN)) >= MAXPATHLEN)
		pos = MAXPATHLEN - 1;

	while (pos > 0 && path[pos-1] != '/')
		pos--;
	pos += strlcpy(path+pos, ".rsync", MAXPATHLEN-pos);

	if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
		errno = ETXTBSY;
		return -1;
	}

	/* start where the last one left off to reduce chance of clashes */
	start = counter;
	do {
		snprintf(&path[pos], MAX_RENAMES_DIGITS+1, "%03d", counter);
		if (++counter >= MAX_RENAMES)
			counter = 1;
	} while ((rc = access(path, 0)) == 0 && counter != start);

	if (INFO_GTE(MISC, 1)) {
		rprintf(FWARNING, "renaming %s to %s because of text busy\n",
			fname, path);
	}

	/* maybe we should return rename()'s exit status? Nah. */
	if (do_rename(fname, path) != 0) {
		errno = ETXTBSY;
		return -1;
	}
	return 0;
#endif
}
Example #9
0
void task_fs(){
#ifdef DEBUG_FS
    printl("in task_fs\n");
#endif
    init_fs();
    MESSAGE message;
    memset(&message,0,sizeof(message));
    while(TRUE){
        send_receive(RECEIVE,ANY,&message);
        
        int source_pid=message.source_pid;
        int fd;
	
        switch(message.type){
        case INFO_FS_CREATE:
            message.res_bool=do_create(&message);
            break;
        case INFO_FS_UNLINK:
            message.res_bool=do_unlink(&message);
            break;
        case INFO_FS_LS:
            message.res_int=do_ls(&message);
            break;
        case INFO_FS_OPEN:
            fd=do_open(&message);
            message.fd=fd;
            break;
        case INFO_FS_READ:
            do_read(&message);
            break;
        case INFO_FS_WRITE:
            do_write(&message);
            break;
        case INFO_FS_SEEK:
            do_seek(&message);
            break;
        case INFO_FS_CLOSE:
            message.res_int=do_close(&message);
            break;
        default:
            printl("\n\n\nunknown message type:%d\n",message.type);
            assert(FALSE,"unknown message type!");
        }
        if(message.type!=INFO_SUSPEND_PROCESS){
            send_receive(SEND,source_pid,&message);
        }else{
            printl("inof_suspend_process\n");
        }
    }
#ifndef _FS_H_
#define _FS_H_
    
#endif /* _FS_H_ */
    while(1)
        ;
    spin("never here");
}
Example #10
0
/* Undo a link operation.  */
static void
rollback_link(struct wim_dentry *subject, struct wim_dentry *parent,
	      struct wim_dentry **root_p, struct list_head *orphans)
{
	/* Unlink is the opposite of link  */
	do_unlink(subject, parent, root_p);

	/* @subject is now unlinked.  Add it to orphans. */
	list_add(&subject->tmp_list, orphans);
	subject->is_orphan = 1;
}
Example #11
0
static int
rootfs_rmdir(void *_ns, void *_dir, const char *name)
{
    nspace      *ns;
    vnode       *dir;

    ns = (nspace *) _ns;
    dir = (vnode *) _dir;

    return do_unlink(ns, dir, name, TRUE);
}
Example #12
0
/*      o link newname to oldname
 *      o unlink oldname
 *      o return the value of unlink, or an error
 *
 * Note that this does not provide the same behavior as the
 * Linux system call (if unlink fails then two links to the
 * file could exist).
 */
int do_rename(const char *oldname, const char *newname) {
	/*NOT_YET_IMPLEMENTED("VFS: do_rename");*/
	int retValue;

	retValue = do_link(oldname, newname);

	if (retValue == 0) {
		retValue = do_unlink(oldname);
	}

	return retValue;
}
Example #13
0
/*      o link newname to oldname
 *      o unlink oldname
 *      o return the value of unlink, or an error
 *
 * Note that this does not provide the same behavior as the
 * Linux system call (if unlink fails then two links to the
 * file could exist).
 */
int
do_rename(const char *oldname, const char *newname)
{
	int ret;
	ret = do_link(oldname, newname);
	if (ret<0)
    {
        dbg(DBG_PRINT,"(GRADING2D)\n");
        return ret;
    }
	return do_unlink(oldname);
}
Example #14
0
/*
 * Process a control file.
 */
void
process(const struct printer *pp, char *file)
{
	FILE *cfp;

	if (!chk(file))
		return;
	seteuid(euid);
	if ((cfp = fopen(file, "r")) == NULL)
		fatal(pp, "cannot open %s", file);
	seteuid(uid);
	while (getline(cfp)) {
		switch (line[0]) {
		case 'U':  /* unlink associated files */
			if (strchr(line+1, '/') || strncmp(line+1, "df", 2))
				break;
			do_unlink(line+1);
		}
	}
	(void) fclose(cfp);
	do_unlink(file);
}
/*      o link newname to oldname
 *      o unlink oldname
 *      o return the value of unlink, or an error
 *
 * Note that this does not provide the same behavior as the
 * Linux system call (if unlink fails then two links to the
 * file could exist).
 */
int
do_rename(const char *oldname, const char *newname)
{
        /*NOT_YET_IMPLEMENTED("VFS: do_rename");
        return 0;*/
    
        int retVal;
    
        retVal = do_link(oldname, newname);
        if (!retVal){
            return retVal;
        }
    
        return do_unlink(oldname);
}
/* 
 * A function executed by a thread that creates a directory called /dir00n
 * (where n is arg1) and unlinks 50 files from it called /dir00n/test000 through
 * /dir00n/test049.  Ignore the return codes (files may not be there yet).
 * Threads running this are created by kshell_directory_test.  Structurally
 * similar to make_dir_thread. 
 */
static void *rm_dir_thread(int arg1, void *arg2) {
	char dir[TESTBUFLEN];	/* Directory pathname */
	char file[TESTBUFLEN];	/* Each file's pathname */
	int rv = 0;		/* Return value */
	int i = 0;		/* Scratch */

	/* Make the directory */
	snprintf(dir, TESTBUFLEN, "/dir%03d", arg1);
	do_mkdir(dir);

	/* Unlink the files */
	for (i = 0; i < 50 ; i++ ) {
	    snprintf(file, TESTBUFLEN, "%s/test%03d", dir, i);
	    do_unlink(file);
	}
	do_exit(rv);
	return NULL;
}
Example #17
0
/*      o link newname to oldname
 *      o unlink oldname
 *      o return the value of unlink, or an error
 *
 * Note that this does not provide the same behavior as the
 * Linux system call (if unlink fails then two links to the
 * file could exist).
 */
int
do_rename(const char *oldname, const char *newname)
{
    /* NOT_YET_IMPLEMENTED("VFS: do_rename"); */
    
    /* Make sure name is not NULL. */
    if ((oldname == NULL) || (newname == NULL)) {
	    return -EINVAL;
    }
    
    int ret = 0;
    ret = do_link(oldname, newname); /*Order is right now.*/
    if (ret) {
        return ret;
    }
    ret = do_unlink(oldname);
    return ret;
}
Example #18
0
/**************************************************************************************************
 * 					task_fs
 **************************************************************************************************
 * <Ring 1> Main loop of Task FS.
 *************************************************************************************************/
PUBLIC void task_fs(){
	init_fs();

	while(TRUE){
		send_recv(RECEIVE, ANY, &fs_msg);
		int src	= fs_msg.source;
		pcaller	= &proc_table[src];

		switch(fs_msg.type){
			case OPEN:
			fs_msg.FD	= do_open();
			break;
		case CLOSE:
			fs_msg.RETVAL	= do_close();
			break;
		case READ:
		case WRITE:
			fs_msg.CNT	= do_rdwt();
			break;
		case UNLINK:
			fs_msg.RETVAL	= do_unlink();
			break;
		case RESUME_PROC:
			src = fs_msg.PROC_NR;
			break;
		case FORK:
			fs_msg.RETVAL	= fs_fork();
			break;
		default:
			dump_msg("FS::unkown message:", &fs_msg);
			assert(0);
			break;
		}
		/* reply */
		if(fs_msg.type != SUSPEND_PROC){
			fs_msg.type	= SYSCALL_RET;
			send_recv(SEND, src, &fs_msg);
		}
	}
	spin("FS");
}
Example #19
0
/* robustly move a file, creating new directory structures if necessary */
static int robust_move(char *src, char *dst)
{
	int keep_trying = 4;
	int keep_path_extfs = 0;
	int failed;

	while (keep_trying) {
		if (keep_path_extfs) {
			failed = copy_file(src, dst, 0755);
			if (!failed) {
				do_unlink(src);
			}
		} else {
			failed = robust_rename (src, dst);
		}

		if (failed) {
			if (verbose > 2)
				rprintf (FERROR, "robust_move failed: %s(%d)\n",
					strerror (errno), errno);
			switch (errno) {
				/* external filesystem */
				case EXDEV:
					keep_path_extfs = 1;
					keep_trying--;
					break;
				/* no directory to write to */
				case ENOENT:
					make_dir (dst, 0755);
					keep_trying--;
					break;
				default:
					keep_trying = 0;
			} /* switch */
		} else
			keep_trying = 0;
	} /* while */
	return (!failed);
} /* robust_move */
Example #20
0
/*      o link newname to oldname
 *      o unlink oldname
 *      o return the value of unlink, or an error
 *
 * Note that this does not provide the same behavior as the
 * Linux system call (if unlink fails then two links to the
 * file could exist).
 */
int
do_rename(const char *oldname, const char *newname)
{
        if(strlen(oldname) <=0)
        {
                dbg(DBG_PRINT,"(GRADING2D) String length of oldname not valid\n");
                dbg(DBG_ERROR,"String length of oldname not valid\n");
                return -EINVAL;
        }
        if(strlen(newname) <=0)
        {
                dbg(DBG_PRINT,"(GRADING2D) String length of newname not valid\n");
                dbg(DBG_ERROR,"String length of newname not valid\n");
                return -EINVAL;
        }

         dbg(DBG_PRINT,"(GRADING2D) the name was changed \n");
        do_link(oldname,newname);
        return do_unlink(oldname);

        /*NOT_YET_IMPLEMENTED("VFS: do_rename");
        return -1;*/
}
Example #21
0
static int sys_unlink(argstr_t *arg)
{
    argstr_t                kern_args;
    char                    *path;
    int                     err;
    
    if ((err = copy_from_user(&kern_args, arg, sizeof(argstr_t))) < 0) {
        curthr->kt_errno = -err;
        return -1;
    }
    
    path = user_strdup(&kern_args);
    if (!path) {
        curthr->kt_errno = EINVAL;
        return -1;
    }
    
    err = do_unlink(path);
    kfree(path);
    if (err < 0) {
        curthr->kt_errno = -err;
        return -1;
    } else return err;
}
Example #22
0
/*      o link newname to oldname
 *      o unlink oldname
 *      o return the value of unlink, or an error
 *
 * Note that this does not provide the same behavior as the
 * Linux system call (if unlink fails then two links to the
 * file could exist).
 */
int
do_rename(const char *oldname, const char *newname)
{
	/* NOT_YET_IMPLEMENTED("VFS: do_rename"); */

	/*GS: oldname and newname should point to something */
	KASSERT(oldname);
	KASSERT(newname);

    dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");
	/*GS: link newname to oldname*/
	int retVal = do_link(oldname,newname);

	/* GS: NOTE! - need to confirm do_link error values after implemented */
	if( retVal < 0)
	{
		dbg(DBG_PRINT, "(GRADING2C 1.m) (vfs_syscall.c) (do_rename) error do_link, return error\n");
		return retVal;
	}

	/*GS: unlink oldname and return the value of unlink */
	return do_unlink(oldname);

}
Example #23
0
/**
 * <Ring 1> The main loop of TASK FS.
 * 
 *****************************************************************************/
PUBLIC void task_fs()
{
	printl("{FS} Task FS begins.\n");

	init_fs();

	while (1) {
		send_recv(RECEIVE, ANY, &fs_msg);

		int msgtype = fs_msg.type;
		int src = fs_msg.source;
		pcaller = &proc_table[src];

		switch (msgtype) {
		case OPEN:
			fs_msg.FD = do_open();
			break;
		case CLOSE:
			fs_msg.RETVAL = do_close();
			break;
		case READ:
		case WRITE:
			fs_msg.CNT = do_rdwt();
			break;
		case UNLINK:
			fs_msg.RETVAL = do_unlink();
			break;
		case RESUME_PROC:
			src = fs_msg.PROC_NR;
			break;
		case FORK:
			fs_msg.RETVAL = fs_fork();
			break;
		case EXIT:
			fs_msg.RETVAL = fs_exit();
			break;
		/* case LSEEK: */
		/* 	fs_msg.OFFSET = do_lseek(); */
		/* 	break; */
		case STAT:
			fs_msg.RETVAL = do_stat();
			break;
		default:
			dump_msg("FS::unknown message:", &fs_msg);
			assert(0);
			break;
		}

#ifdef ENABLE_DISK_LOG
		char * msg_name[128];
		msg_name[OPEN]   = "OPEN";
		msg_name[CLOSE]  = "CLOSE";
		msg_name[READ]   = "READ";
		msg_name[WRITE]  = "WRITE";
		msg_name[LSEEK]  = "LSEEK";
		msg_name[UNLINK] = "UNLINK";
		/* msg_name[FORK]   = "FORK"; */
		/* msg_name[EXIT]   = "EXIT"; */
		/* msg_name[STAT]   = "STAT"; */

		switch (msgtype) {
		case UNLINK:
			dump_fd_graph("%s just finished. (pid:%d)",
				      msg_name[msgtype], src);
			//panic("");
		case OPEN:
		case CLOSE:
		case READ:
		case WRITE:
		case FORK:
		case EXIT:
		/* case LSEEK: */
		case STAT:
			break;
		case RESUME_PROC:
			break;
		default:
			assert(0);
		}
#endif

		/* reply */
		if (fs_msg.type != SUSPEND_PROC) {
			fs_msg.type = SYSCALL_RET;
			send_recv(SEND, src, &fs_msg);
		}
	}
}
/**
 * main routine for receiver process.
 *
 * Receiver process runs on the same host as the generator process. */
int recv_files(int f_in, char *local_name)
{
	int fd1,fd2;
	STRUCT_STAT st;
	int iflags, xlen;
	char *fname, fbuf[MAXPATHLEN];
	char xname[MAXPATHLEN];
	char fnametmp[MAXPATHLEN];
	char *fnamecmp, *partialptr;
	char fnamecmpbuf[MAXPATHLEN];
	uchar fnamecmp_type;
	struct file_struct *file;
	struct stats initial_stats;
	int itemizing = am_server ? logfile_format_has_i : stdout_format_has_i;
	enum logcode log_code = log_before_transfer ? FLOG : FINFO;
	int max_phase = protocol_version >= 29 ? 2 : 1;
	int dflt_perms = (ACCESSPERMS & ~orig_umask);
#ifdef SUPPORT_ACLS
	const char *parent_dirname = "";
#endif
	int ndx, recv_ok;

	if (verbose > 2)
		rprintf(FINFO, "recv_files(%d) starting\n", cur_flist->used);

	if (delay_updates)
		delayed_bits = bitbag_create(cur_flist->used + 1);

	while (1) {
		cleanup_disable();

		/* This call also sets cur_flist. */
		ndx = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type,
					 xname, &xlen);
		if (ndx == NDX_DONE) {
			if (inc_recurse && first_flist) {
				if (read_batch)
					gen_wants_ndx(first_flist->used + first_flist->ndx_start);
				flist_free(first_flist);
				if (first_flist)
					continue;
			} else if (read_batch && first_flist)
				gen_wants_ndx(first_flist->used);
			if (++phase > max_phase)
				break;
			if (verbose > 2)
				rprintf(FINFO, "recv_files phase=%d\n", phase);
			if (phase == 2 && delay_updates)
				handle_delayed_updates(local_name);
			send_msg(MSG_DONE, "", 0, 0);
			continue;
		}

		if (ndx - cur_flist->ndx_start >= 0)
			file = cur_flist->files[ndx - cur_flist->ndx_start];
		else
			file = dir_flist->files[cur_flist->parent_ndx];
		fname = local_name ? local_name : f_name(file, fbuf);

		if (verbose > 2)
			rprintf(FINFO, "recv_files(%s)\n", fname);

#ifdef SUPPORT_XATTRS
		if (iflags & ITEM_REPORT_XATTR && !dry_run)
			recv_xattr_request(file, f_in);
#endif

		if (!(iflags & ITEM_TRANSFER)) {
			maybe_log_item(file, iflags, itemizing, xname);
#ifdef SUPPORT_XATTRS
			if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && !dry_run)
				set_file_attrs(fname, file, NULL, fname, 0);
#endif
			continue;
		}
		if (phase == 2) {
			rprintf(FERROR,
				"got transfer request in phase 2 [%s]\n",
				who_am_i());
			exit_cleanup(RERR_PROTOCOL);
		}

		if (file->flags & FLAG_FILE_SENT) {
			if (csum_length == SHORT_SUM_LENGTH) {
				if (keep_partial && !partial_dir)
					make_backups = -make_backups; /* prevents double backup */
				if (append_mode)
					sparse_files = -sparse_files;
				append_mode = -append_mode;
				csum_length = SUM_LENGTH;
				redoing = 1;
			}
		} else {
			if (csum_length != SHORT_SUM_LENGTH) {
				if (keep_partial && !partial_dir)
					make_backups = -make_backups;
				if (append_mode)
					sparse_files = -sparse_files;
				append_mode = -append_mode;
				csum_length = SHORT_SUM_LENGTH;
				redoing = 0;
			}
		}

		if (!am_server && do_progress)
			set_current_file_index(file, ndx);
		stats.num_transferred_files++;
		stats.total_transferred_size += F_LENGTH(file);

		cleanup_got_literal = 0;

		if (daemon_filter_list.head
		    && check_filter(&daemon_filter_list, FLOG, fname, 0) < 0) {
			rprintf(FERROR, "attempt to hack rsync failed.\n");
			exit_cleanup(RERR_PROTOCOL);
		}

		if (!do_xfers) { /* log the transfer */
			log_item(FCLIENT, file, &stats, iflags, NULL);
			if (read_batch)
				discard_receive_data(f_in, F_LENGTH(file));
			continue;
		}
		if (write_batch < 0) {
			log_item(FCLIENT, file, &stats, iflags, NULL);
			if (!am_server)
				discard_receive_data(f_in, F_LENGTH(file));
			continue;
		}

		if (read_batch) {
			if (!(redoing ? we_want_redo(ndx) : gen_wants_ndx(ndx))) {
				rprintf(FINFO,
					"(Skipping batched update for%s \"%s\")\n",
					redoing ? " resend of" : "",
					fname);
				discard_receive_data(f_in, F_LENGTH(file));
				file->flags |= FLAG_FILE_SENT;
				continue;
			}
		}

		partialptr = partial_dir ? partial_dir_fname(fname) : fname;

		if (protocol_version >= 29) {
			switch (fnamecmp_type) {
			case FNAMECMP_FNAME:
				fnamecmp = fname;
				break;
			case FNAMECMP_PARTIAL_DIR:
				fnamecmp = partialptr;
				break;
			case FNAMECMP_BACKUP:
				fnamecmp = get_backup_name(fname);
				break;
			case FNAMECMP_FUZZY:
				if (file->dirname) {
					pathjoin(fnamecmpbuf, MAXPATHLEN,
						 file->dirname, xname);
					fnamecmp = fnamecmpbuf;
				} else
					fnamecmp = xname;
				break;
			default:
				if (fnamecmp_type >= basis_dir_cnt) {
					rprintf(FERROR,
						"invalid basis_dir index: %d.\n",
						fnamecmp_type);
					exit_cleanup(RERR_PROTOCOL);
				}
				pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
					 basis_dir[fnamecmp_type], fname);
				fnamecmp = fnamecmpbuf;
				break;
			}
			if (!fnamecmp || (daemon_filter_list.head
			  && check_filter(&daemon_filter_list, FLOG, fname, 0) < 0)) {
				fnamecmp = fname;
				fnamecmp_type = FNAMECMP_FNAME;
			}
		} else {
			/* Reminder: --inplace && --partial-dir are never
			 * enabled at the same time. */
			if (inplace && make_backups > 0) {
				if (!(fnamecmp = get_backup_name(fname)))
					fnamecmp = fname;
				else
					fnamecmp_type = FNAMECMP_BACKUP;
			} else if (partial_dir && partialptr)
				fnamecmp = partialptr;
			else
				fnamecmp = fname;
		}

		initial_stats = stats;

		/* open the file */
		fd1 = do_open(fnamecmp, O_RDONLY, 0);

		if (fd1 == -1 && protocol_version < 29) {
			if (fnamecmp != fname) {
				fnamecmp = fname;
				fd1 = do_open(fnamecmp, O_RDONLY, 0);
			}

			if (fd1 == -1 && basis_dir[0]) {
				/* pre-29 allowed only one alternate basis */
				pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
					 basis_dir[0], fname);
				fnamecmp = fnamecmpbuf;
				fd1 = do_open(fnamecmp, O_RDONLY, 0);
			}
		}

		updating_basis_or_equiv = inplace
		    && (fnamecmp == fname || fnamecmp_type == FNAMECMP_BACKUP);

		if (fd1 == -1) {
			st.st_mode = 0;
			st.st_size = 0;
		} else if (do_fstat(fd1,&st) != 0) {
			rsyserr(FERROR_XFER, errno, "fstat %s failed",
				full_fname(fnamecmp));
			discard_receive_data(f_in, F_LENGTH(file));
			close(fd1);
			if (inc_recurse)
				send_msg_int(MSG_NO_SEND, ndx);
			continue;
		}

		if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
			/* this special handling for directories
			 * wouldn't be necessary if robust_rename()
			 * and the underlying robust_unlink could cope
			 * with directories
			 */
			rprintf(FERROR_XFER, "recv_files: %s is a directory\n",
				full_fname(fnamecmp));
			discard_receive_data(f_in, F_LENGTH(file));
			close(fd1);
			if (inc_recurse)
				send_msg_int(MSG_NO_SEND, ndx);
			continue;
		}

		if (fd1 != -1 && !S_ISREG(st.st_mode)) {
			close(fd1);
			fd1 = -1;
		}

		/* If we're not preserving permissions, change the file-list's
		 * mode based on the local permissions and some heuristics. */
		if (!preserve_perms) {
			int exists = fd1 != -1;
#ifdef SUPPORT_ACLS
			const char *dn = file->dirname ? file->dirname : ".";
			if (parent_dirname != dn
			 && strcmp(parent_dirname, dn) != 0) {
				dflt_perms = default_perms_for_dir(dn);
				parent_dirname = dn;
			}
#endif
			file->mode = dest_mode(file->mode, st.st_mode,
					       dflt_perms, exists);
		}

		/* We now check to see if we are writing the file "inplace" */
		if (inplace)  {
			fd2 = do_open(fname, O_WRONLY|O_CREAT, 0600);
			if (fd2 == -1) {
				rsyserr(FERROR_XFER, errno, "open %s failed",
					full_fname(fname));
			}
		} else {
			fd2 = open_tmpfile(fnametmp, fname, file);
			if (fd2 != -1)
				cleanup_set(fnametmp, partialptr, file, fd1, fd2);
		}

		if (fd2 == -1) {
			discard_receive_data(f_in, F_LENGTH(file));
			if (fd1 != -1)
				close(fd1);
			if (inc_recurse)
				send_msg_int(MSG_NO_SEND, ndx);
			continue;
		}

		/* log the transfer */
		if (log_before_transfer)
			log_item(FCLIENT, file, &initial_stats, iflags, NULL);
		else if (!am_server && verbose && do_progress)
			rprintf(FINFO, "%s\n", fname);

		/* recv file data */
		recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
				       fname, fd2, F_LENGTH(file));

		log_item(log_code, file, &initial_stats, iflags, NULL);

		if (fd1 != -1)
			close(fd1);
		if (close(fd2) < 0) {
			rsyserr(FERROR, errno, "close failed on %s",
				full_fname(fnametmp));
			exit_cleanup(RERR_FILEIO);
		}

		if ((recv_ok && (!delay_updates || !partialptr)) || inplace) {
			if (partialptr == fname)
				partialptr = NULL;
			if (!finish_transfer(fname, fnametmp, fnamecmp,
					     partialptr, file, recv_ok, 1))
				recv_ok = -1;
			else if (fnamecmp == partialptr) {
				do_unlink(partialptr);
				handle_partial_dir(partialptr, PDIR_DELETE);
			}
		} else if (keep_partial && partialptr) {
			if (!handle_partial_dir(partialptr, PDIR_CREATE)) {
				rprintf(FERROR,
				    "Unable to create partial-dir for %s -- discarding %s.\n",
				    local_name ? local_name : f_name(file, NULL),
				    recv_ok ? "completed file" : "partial file");
				do_unlink(fnametmp);
				recv_ok = -1;
			} else if (!finish_transfer(partialptr, fnametmp, fnamecmp, NULL,
						    file, recv_ok, !partial_dir))
				recv_ok = -1;
			else if (delay_updates && recv_ok) {
				bitbag_set_bit(delayed_bits, ndx);
				recv_ok = 2;
			} else
				partialptr = NULL;
		} else
			do_unlink(fnametmp);

		cleanup_disable();

		if (read_batch)
			file->flags |= FLAG_FILE_SENT;

		switch (recv_ok) {
		case 2:
			break;
		case 1:
			if (remove_source_files || inc_recurse
			 || (preserve_hard_links && F_IS_HLINKED(file)))
				send_msg_int(MSG_SUCCESS, ndx);
			break;
		case 0: {
			enum logcode msgtype = redoing ? FERROR_XFER : FWARNING;
			if (msgtype == FERROR_XFER || verbose) {
				char *errstr, *redostr, *keptstr;
				if (!(keep_partial && partialptr) && !inplace)
					keptstr = "discarded";
				else if (partial_dir)
					keptstr = "put into partial-dir";
				else
					keptstr = "retained";
				if (msgtype == FERROR_XFER) {
					errstr = "ERROR";
					redostr = "";
				} else {
					errstr = "WARNING";
					redostr = read_batch ? " (may try again)"
							     : " (will try again)";
				}
				rprintf(msgtype,
					"%s: %s failed verification -- update %s%s.\n",
					errstr, local_name ? f_name(file, NULL) : fname,
					keptstr, redostr);
			}
			if (!redoing) {
				if (read_batch)
					flist_ndx_push(&batch_redo_list, ndx);
				send_msg_int(MSG_REDO, ndx);
				file->flags |= FLAG_FILE_SENT;
			} else if (inc_recurse)
				send_msg_int(MSG_NO_SEND, ndx);
			break;
		    }
		case -1:
			if (inc_recurse)
				send_msg_int(MSG_NO_SEND, ndx);
			break;
		}
	}
	if (make_backups < 0)
		make_backups = -make_backups;

	if (phase == 2 && delay_updates) /* for protocol_version < 29 */
		handle_delayed_updates(local_name);

	if (verbose > 2)
		rprintf(FINFO,"recv_files finished\n");

	return 0;
}
Example #25
0
int restore_line(const char *filename,uint64_t lv,char *line) {
	char *ptr;
	uint32_t ts;
	int status;
	char* errormsgs[]={ ERROR_STRINGS };

	status = ERROR_MISMATCH;
	ptr = line;

	EAT(ptr,filename,lv,':');
	EAT(ptr,filename,lv,' ');
	GETU32(ts,ptr);
	EAT(ptr,filename,lv,'|');
	switch (*ptr) {
		case 'A':
			if (strncmp(ptr,"ACCESS",6)==0) {
				status = do_access(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"ATTR",4)==0) {
				status = do_attr(filename,lv,ts,ptr+4);
			} else if (strncmp(ptr,"APPEND",6)==0) {
				status = do_append(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"ACQUIRE",7)==0) {
				status = do_acquire(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"AQUIRE",6)==0) {
				status = do_acquire(filename,lv,ts,ptr+6);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'C':
			if (strncmp(ptr,"CREATE",6)==0) {
				status = do_create(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"CUSTOMER",8)==0) {	// deprecated
				status = do_session(filename,lv,ts,ptr+8);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'E':
			if (strncmp(ptr,"EMPTYTRASH",10)==0) {
				status = do_emptytrash(filename,lv,ts,ptr+10);
			} else if (strncmp(ptr,"EMPTYRESERVED",13)==0) {
				status = do_emptyreserved(filename,lv,ts,ptr+13);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'F':
			if (strncmp(ptr,"FREEINODES",10)==0) {
				status = do_freeinodes(filename,lv,ts,ptr+10);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'I':
			if (strncmp(ptr,"INCVERSION",10)==0) {
				status = do_incversion(filename,lv,ts,ptr+10);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'L':
			if (strncmp(ptr,"LENGTH",6)==0) {
				status = do_length(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"LINK",4)==0) {
				status = do_link(filename,lv,ts,ptr+4);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'M':
			if (strncmp(ptr,"MOVE",4)==0) {
				status = do_move(filename,lv,ts,ptr+4);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'P':
			if (strncmp(ptr,"PURGE",5)==0) {
				status = do_purge(filename,lv,ts,ptr+5);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'Q':
			if (strncmp(ptr,"QUOTA",5)==0) {
				status = do_quota(filename,lv,ts,ptr+5);
			}
			break;
		case 'R':
			if (strncmp(ptr,"RELEASE",7)==0) {
				status = do_release(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"REPAIR",6)==0) {
				status = do_repair(filename,lv,ts,ptr+6);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'S':
			if (strncmp(ptr,"SETEATTR",8)==0) {
				status = do_seteattr(filename,lv,ts,ptr+8);
			} else if (strncmp(ptr,"SETGOAL",7)==0) {
				status = do_setgoal(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"SETPATH",7)==0) {
				status = do_setpath(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"SETTRASHTIME",12)==0) {
				status = do_settrashtime(filename,lv,ts,ptr+12);
			} else if (strncmp(ptr,"SETXATTR",8)==0) {
				status = do_setxattr(filename,lv,ts,ptr+8);
			} else if (strncmp(ptr,"SNAPSHOT",8)==0) {
				status = do_snapshot(filename,lv,ts,ptr+8);
			} else if (strncmp(ptr,"SYMLINK",7)==0) {
				status = do_symlink(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"SESSION",7)==0) {
				status = do_session(filename,lv,ts,ptr+7);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'T':
			if (strncmp(ptr,"TRUNC",5)==0) {
				status = do_trunc(filename,lv,ts,ptr+5);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'U':
			if (strncmp(ptr,"UNLINK",6)==0) {
				status = do_unlink(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"UNDEL",5)==0) {
				status = do_undel(filename,lv,ts,ptr+5);
			} else if (strncmp(ptr,"UNLOCK",6)==0) {
				status = do_unlock(filename,lv,ts,ptr+6);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'W':
			if (strncmp(ptr,"WRITE",5)==0) {
				status = do_write(filename,lv,ts,ptr+5);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		default:
			printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
	}
	if (status>STATUS_OK) {
		printf("%s:%"PRIu64": error: %d (%s)\n",filename,lv,status,errormsgs[status]);
	}
	return status;
}
Example #26
0
/**
 * Eventually calls exit(), passing @p code, therefore does not return.
 *
 * @param code one of the RERR_* codes from errcode.h.
 **/
NORETURN void _exit_cleanup(int code, const char *file, int line)
{
	static int switch_step = 0;
	static int exit_code = 0, exit_line = 0;
	static const char *exit_file = NULL;
	static int first_code = 0;

	SIGACTION(SIGUSR1, SIG_IGN);
	SIGACTION(SIGUSR2, SIG_IGN);

	if (!exit_code) { /* Preserve first error exit info when recursing. */
		exit_code = code;
		exit_file = file;
		exit_line = line < 0 ? -line : line;
	}

	/* If this is the exit at the end of the run, the server side
	 * should not attempt to output a message (see log_exit()). */
	if (am_server && code == 0)
		am_server = 2;

	/* Some of our actions might cause a recursive call back here, so we
	 * keep track of where we are in the cleanup and never repeat a step. */
	switch (switch_step) {
#include "case_N.h" /* case 0: */
		switch_step++;

		first_code = code;

		if (output_needs_newline) {
			fputc('\n', stdout);
			output_needs_newline = 0;
		}

		if (DEBUG_GTE(EXIT, 2)) {
			rprintf(FINFO,
				"[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n",
				who_am_i(), code, file, line);
		}

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (cleanup_child_pid != -1) {
			int status;
			int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
			if (pid == cleanup_child_pid) {
				status = WEXITSTATUS(status);
				if (status > exit_code)
					exit_code = status;
			}
		}

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (cleanup_got_literal && (cleanup_fname || cleanup_fd_w != -1)) {
			if (cleanup_fd_r != -1) {
				close(cleanup_fd_r);
				cleanup_fd_r = -1;
			}
			if (cleanup_fd_w != -1) {
				flush_write_file(cleanup_fd_w);
				close(cleanup_fd_w);
				cleanup_fd_w = -1;
			}
			if (cleanup_fname && cleanup_new_fname && keep_partial
			 && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
				int tweak_modtime = 0;
				const char *fname = cleanup_fname;
				cleanup_fname = NULL;
				if (!partial_dir) {
				    /* We don't want to leave a partial file with a modern time or it
				     * could be skipped via --update.  Setting the time to something
				     * really old also helps it to stand out as unfinished in an ls. */
				    tweak_modtime = 1;
				    cleanup_file->modtime = 0;
				}
				finish_transfer(cleanup_new_fname, fname, NULL, NULL,
						cleanup_file, tweak_modtime, !partial_dir);
			}
		}

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (flush_ok_after_signal) {
			flush_ok_after_signal = False;
			if (code == RERR_SIGNAL)
				io_flush(FULL_FLUSH);
		}
		if (!exit_code && !code)
			io_flush(FULL_FLUSH);

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (cleanup_fname)
			do_unlink(cleanup_fname);
		if (exit_code)
			kill_all(SIGUSR1);
		if (cleanup_pid && cleanup_pid == getpid()) {
			char *pidf = lp_pid_file();
			if (pidf && *pidf)
				unlink(lp_pid_file());
		}

		if (exit_code == 0) {
			if (code)
				exit_code = code;
			if (io_error & IOERR_DEL_LIMIT)
				exit_code = RERR_DEL_LIMIT;
			if (io_error & IOERR_VANISHED)
				exit_code = RERR_VANISHED;
			if (io_error & IOERR_GENERAL || got_xfer_error)
				exit_code = RERR_PARTIAL;
		}

		/* If line < 0, this exit is after a MSG_ERROR_EXIT event, so
		 * we don't want to output a duplicate error. */
		if ((exit_code && line > 0)
		 || am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1))))
			log_exit(exit_code, exit_file, exit_line);

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (DEBUG_GTE(EXIT, 1)) {
			rprintf(FINFO,
				"[%s] _exit_cleanup(code=%d, file=%s, line=%d): "
				"about to call exit(%d)\n",
				who_am_i(), first_code, exit_file, exit_line, exit_code);
		}

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (exit_code && exit_code != RERR_SOCKETIO && exit_code != RERR_STREAMIO && exit_code != RERR_SIGNAL1
		 && exit_code != RERR_TIMEOUT && !shutting_down && (protocol_version >= 31 || am_receiver)) {
			if (line > 0) {
				if (DEBUG_GTE(EXIT, 3)) {
					rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n",
						who_am_i(), exit_code);
				}
				send_msg_int(MSG_ERROR_EXIT, exit_code);
			}
			noop_io_until_death();
		}

		/* FALLTHROUGH */
#include "case_N.h"
		switch_step++;

		if (am_server && exit_code)
			msleep(100);
		close_all();

		/* FALLTHROUGH */
	default:
		break;
	}

	exit(exit_code);
}
Example #27
0
static int directio_test(void)
{
	int ret, fd;
	char dest[PATH_MAX];
	int sub_testno = 1;
	int o_flags_rw, o_flags_ro;

	unsigned long write_size = 0, read_size = 0;
	unsigned long append_size = 0, truncate_size = 0;
	unsigned long interval, offset = 0;

	unsigned long align_slice = 512;
	unsigned long align_filesz = align_slice;

	o_flags_rw = open_rw_flags;
	o_flags_ro = open_ro_flags;

	open_rw_flags |= O_DIRECT;
	open_ro_flags |= O_DIRECT;

	while (align_filesz < file_size)
		align_filesz += align_slice;

	root_printf("Test %d: Multi-nodes O_DIRECT test.\n", testno++);

	snprintf(orig_path, PATH_MAX, "%s/multi_original_directio_refile",
		 workplace);

	root_printf("  *SubTest %d:Prepare original inode %s.\n",
		    sub_testno++, orig_path);

	if (!rank) {

		ret = prep_orig_file_dio(orig_path, align_filesz);
		should_exit(ret);
	}

	MPI_Barrier_Sync();

	/*
	* All ranks try to reflink the original to increment the
	* refcount concurrently.
	*/
	root_printf("  *SubTest %d:Reflinking inode %s among nodes.\n",
		    sub_testno++, orig_path);

	if (rank) {

		snprintf(dest, PATH_MAX, "%s-%s-%d", orig_path, hostname, rank);
		ret = reflink(orig_path, dest, 1);
		should_exit(ret);
	}

	MPI_Barrier_Sync();

	/*
	* All ranks try to do cow to decrement the
	* refcount concurrently.
	*/

	root_printf("  *SubTest %d:Cowing reflinks by O_DIRECT writes among"
		    " nodes.\n", sub_testno++);
	if (rank) {

		snprintf(dest, PATH_MAX, "%s-%s-%d", orig_path, hostname, rank);
		interval = DIRECTIO_SLICE;
		offset = 0;

		while (offset < align_filesz) {

			write_size = DIRECTIO_SLICE;

			if (offset + write_size > align_filesz)
				write_size = align_filesz - offset;

			get_rand_buf(dio_buf, write_size);

			ret = write_at_file(dest, dio_buf, write_size, offset);

			should_exit(ret);

			offset += write_size + interval;
		}
	}

	MPI_Barrier_Sync();

	/*
	* All ranks try to read reflinks concurrently
	*/
	root_printf("  *SubTest %d:O_DIRECT reading reflinks among nodes.\n",
		    sub_testno++);

	if (rank) {

		snprintf(dest, PATH_MAX, "%s-%s-%d", orig_path, hostname, rank);
		interval = DIRECTIO_SLICE;
		offset = 0;

		while (offset < align_filesz) {

			read_size = DIRECTIO_SLICE;

			if (offset + read_size > align_filesz)
				read_size = align_filesz - offset;

			ret = read_at_file(dest, dio_buf, read_size, offset);

			should_exit(ret);

			offset = offset + read_size + interval;
		}

	}

	MPI_Barrier_Sync();

	/*
	* All ranks try to append reflinks concurrently
	*/

       root_printf("  *SubTest %d:Appending reflinks among nodes.\n",
		   sub_testno++);

	if (rank) {

		snprintf(dest, PATH_MAX, "%s-%s-%d", orig_path, hostname, rank);
		fd = open64(dest, open_rw_flags | O_APPEND);
		if (fd < 0) {
			fd = errno;
			abort_printf("open file %s failed:%d:%s\n",
				     dest, fd, strerror(fd));
		}

		append_size = DIRECTIO_SLICE;

		get_rand_buf(dio_buf, append_size);

		ret = write(fd, dio_buf, append_size);
		if (ret < 0) {
			ret = errno;
			abort_printf("write file %s failed:%d:%s\n",
				     dest, ret, strerror(ret));
		}

		close(fd);
	}

	MPI_Barrier_Sync();

	/*
	* All ranks try to truncate reflinks concurrently
	*/

	root_printf("  *SubTest %d:Truncating reflinks among nodes.\n",
		    sub_testno++);

	if (rank) {

		snprintf(dest, PATH_MAX, "%s-%s-%d", orig_path, hostname, rank);

		truncate_size = get_rand(0, align_filesz / DIRECTIO_SLICE) *
					DIRECTIO_SLICE;

		ret = truncate(dest, truncate_size);

		if (ret < 0) {
			ret = errno;
			abort_printf("truncate file %s failed:%d:%s\n",
				     dest, ret, strerror(ret));
		}
	}

	MPI_Barrier_Sync();

	if (rank) {

		ret = do_unlink(dest);
		should_exit(ret);

	} else {

		ret = do_unlink(orig_path);
		should_exit(ret);
	}

	open_rw_flags = o_flags_rw;
	open_ro_flags = o_flags_ro;

	MPI_Barrier_Sync();

	return 0;
}
Example #28
0
int vfs_selftest(kshell_t *kshell, int argc, char **argv)
{
  int fd1,fd2;
  char *y="/ab/fil";
  char x[2];
  int err;
  do_mkdir("/ab");
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  fd1=do_open("/ab/new",2);
  fd2=do_dup2(fd1,NFILES+1);
  if(fd2<0)
    {
      dbg(DBG_PRINT,"File not created\n");
    }
  do_mknod("/ab/notmade",4096,MKDEVID(1,1));
  do_mknod("/ab/new/not",S_IFCHR,MKDEVID(1,1));
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  do_mknod("", S_IFCHR,MKDEVID(1,1));

  /*do_close(fd1);*/
    for(fd2=1;fd2<35;fd2++)
    {
      sprintf(x,"%d",fd2);
      strcat(y,x);
      do_mknod(y,S_IFCHR,MKDEVID(1,0));
      err=do_open(y,2);
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
      
    }
do_mknod("/ab/new1", S_IFCHR,MKDEVID(1,1));
 err=do_dup(fd1);
  do_unlink("/ab/new/ab");
 do_unlink("/ab/new");
 do_close(fd1);
 for(fd2=NFILES-1;fd2>0;fd2--)
   {
     err=do_close(fd2);
     sprintf(x,"%d",fd2);
      strcat(y,x);
      do_unlink(y);  
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
   }
 do_link("/a","/dev");
 do_link("/dev","/a");
 do_link("/dev","/a");
 do_rmdir("/a");
 /* mkdir("/k");
    do_link("/ab","/k");*/
  do_rmdir("/ab");
  /*do_rmdir("/k");*/

 /*GS: SELF TESTS*/
    dbg(DBG_PRINT,"\n*************************************************************\n");
    dbg(DBG_PRINT,"\n\n\n\n(GRADING2C)(kmain.c)(selftest_proc_run) selftests begin\n");

    int retVal = 0;
    int i = 0;

    /* 1. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_stat)  strlen too long, return -ENAMETOOLONG\n");*/
    char longPath[1024 + 1] = {0};
    for(i = 0; i < 1025; i++)
        longPath[i] = 'a';
    struct stat buf;
    retVal = do_stat(longPath, &buf);
    retVal=do_chdir(longPath);

    /*2. dbg(DBG_PRINT, "(GRADING2B) ENOTDIR or ENOENT\n");*/
    retVal = do_stat("", &buf);

    /*3. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    struct dirent dirp;
    retVal = do_getdent(-1, &dirp);

    /*4. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    retVal = do_getdent(1, &dirp);

    /*5. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) File descriptor does not refer to a directory, return -ENOTDIR\n");*/
    do_mknod("/./file", S_IFCHR,MKDEVID(1,1));
    fd1 = do_open("/./file",2);
    retVal = do_getdent(fd1, &dirp);

    do_unlink("/./file");
    do_close(fd1);
    /*6. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");*/
    /* and */
    /*7. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) error do_link, return error\n"); \n");*/
    retVal = do_rename("/./aaa", "/./bbb");


    dbg(DBG_PRINT,"\n\nretVal=%d",retVal);
    dbg(DBG_PRINT,"\n*************************************************************\n");
  return 0;
}
Example #29
0
void 
do_link(dbref player, dbref cause, int key, char *what, char *where)
{
    dbref thing, room;
    char *buff;
    int nomtest;

    if ( (key & SIDEEFFECT) && !SideFX(player) ) {
       notify(player, "#-1 FUNCTION DISABLED");
       return;
    }

    /* Find the thing to link */

    init_match(player, what, TYPE_EXIT);
    match_everything(0);
    thing = noisy_match_result();
    if (thing == NOTHING)
	return;

    nomtest = ((NoMod(thing) && !WizMod(player)) || (DePriv(player,Owner(thing),DP_MODIFY,POWER7,NOTHING) && (Owner(thing) != Owner(player))) || (Backstage(player) && NoBackstage(thing) && !Immortal(player)));
    /* Allow unlink if where is not specified */

    if (!where || !*where) {
      if (!nomtest)
	do_unlink(player, cause, key, what);
      else
	notify(player,"Permission denied.");
      return;
    }
    switch (Typeof(thing)) {
    case TYPE_EXIT:

	/* Set destination */

	room = parse_linkable_room(player, where);
	if (room != NOTHING) {
	  if (!nomtest)
	    link_exit(player, thing, room, key);
	  else
	    notify(player,"Permission denied.");
	}
	break;
    case TYPE_PLAYER:
    case TYPE_THING:

	/* Set home */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	init_match(player, where, NOTYPE);
	match_everything(MAT_NO_EXITS);
	room = noisy_match_result();
	if (!Good_obj(room))
	    break;
	if (!Has_contents(room)) {
	    notify_quiet(player, "Can't link to an exit.");
	    break;
	}
	if (!can_set_home(player, thing, room) ||
	    !could_doit(player, room, A_LLINK, 1, 0)) {
	    notify_quiet(player, "Permission denied.");
	} else if (room == HOME) {
	    notify_quiet(player, "Can't set home to home.");
	} else {
	    s_Home(thing, room);
	    if (!(Quiet(player) || (key & SIDEEFFECT)) )
		notify_quiet(player, "Home set.");
	}
	break;
    case TYPE_ROOM:

	/* Set dropto */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	room = parse_linkable_room(player, where);
	if (!Good_obj(room) && (room != HOME)) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}

	if ((room != HOME) && !isRoom(room)) {
	    notify_quiet(player, "That is not a room!");
	} else if ((room != HOME) &&
		   ((!controls(player, room) && !Link_ok(room)) ||
		    !could_doit(player, room, A_LLINK, 1, 0))) {
	    notify_quiet(player, "Permission denied.");
	} else {
	    s_Dropto(thing, room);
	    if (!Quiet(player))
		notify_quiet(player, "Dropto set.");
	}
	break;
    default:
	STARTLOG(LOG_BUGS, "BUG", "OTYPE")
	    buff = alloc_mbuf("do_link.LOG.badtype");
	sprintf(buff, "Strange object type: object #%d = %d",
		thing, Typeof(thing));
	log_text(buff);
	free_mbuf(buff);
	ENDLOG
    }
}
Example #30
0
static int comp_test(void)
{

	int ret;
	char dest[PATH_MAX];

	unsigned long i;

	root_printf("Test %d: Multi-nodes comprehensive test.\n", testno++);

	snprintf(orig_path, PATH_MAX, "%s/multi_original_comp_refile",
		 workplace);
	snprintf(dest, PATH_MAX, "%s_target", orig_path);

	if (!rank) {
		ret = prep_orig_file(orig_path, file_size, 1);
		should_exit(ret);
		ret = do_reflinks(orig_path, orig_path, ref_counts, 0);
		should_exit(ret);
		ret = reflink(orig_path, dest, 1);
		should_exit(ret);
	}

	MPI_Barrier_Sync();

	if (rank == 1) {
		/*also doing reflinks and unlinks*/
		printf("  *Test Rank %d: Doing reflinks,cows and unlink.\n",
		       rank);
		ret = do_reflinks(dest, dest, ref_counts, 0);
		should_exit(ret);
		ret = do_cows_on_write(dest, ref_counts, file_size, HUNK_SIZE);
		should_exit(ret);
		ret = do_unlinks(dest, ref_counts);
		should_exit(ret);
	}

	if (rank % 6 == 2) {
		/*Write former reflinks to cause cow*/
		printf("  *Test Rank %d: Doing cows.\n", rank);
		ret = do_cows_on_write(orig_path, ref_counts, file_size,
				       HUNK_SIZE);
		should_exit(ret);
	}

	if (rank % 6 == 3) {
		/*Read former reflinks*/
		printf("  *Test Rank %d: Doing reads.\n", rank);
		ret = do_reads_on_reflinks(orig_path, ref_counts, file_size,
					   HUNK_SIZE);
		should_exit(ret);
	}

	if (rank % 6 == 4) {
		/*Append to former reflinks*/
		printf("  *Test Rank %d: Doing appends.\n", rank);
		ret = do_appends(orig_path, ref_counts);
		should_exit(ret);
	}

	if (rank % 6 == 5) {
		/*Truncate former reflinks*/
		printf("  *Test Rank %d: Doing truncates.\n", rank);
		ret = do_cows_on_ftruncate(orig_path, ref_counts, file_size);
		should_exit(ret);
	}

	if (!rank) {

		printf("  *Test Rank %d: Doing verifications.\n", rank);
		for (i = 0; i < size; i++) {
			ret = verify_orig_file(orig_path);
			should_exit(ret);
			sleep(1);
		}
	}

	MPI_Barrier_Sync();

	if (!rank) {
		printf("  *Test Rank %d: Doing unlinks.\n", rank);
		ret = verify_orig_file(orig_path);
		should_exit(ret);
		ret = do_unlinks(orig_path, ref_counts);
		should_exit(ret);
		ret = do_unlink(orig_path);
		should_exit(ret);
		ret = do_unlink(dest);
		should_exit(ret);
	}

	MPI_Barrier_Sync();

	return 0;
}