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); } } }
/* * 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); }
/* 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); } }
/* 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; }
/* 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; }
/* * 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; }
/* 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; }
/** * 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 }
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"); }
/* 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; }
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); }
/* 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; }
/* 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); }
/* * 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; }
/* 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; }
/************************************************************************************************** * 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"); }
/* 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 */
/* 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;*/ }
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; }
/* 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); }
/** * <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; }
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; }
/** * 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); }
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; }
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; }
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 } }
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; }