int test_mount(int argc, char *argv[]) { const unsigned iterations = 2000; const unsigned alignments = 10; const char *cmd_filename = "/fs/microsd/mount_test_cmds.txt"; /* check if microSD card is mounted */ struct stat buffer; if (stat("/fs/microsd/", &buffer)) { warnx("no microSD card mounted, aborting file test"); return 1; } /* list directory */ DIR *d; struct dirent *dir; d = opendir("/fs/microsd"); if (d) { while ((dir = readdir(d)) != NULL) { //printf("%s\n", dir->d_name); } closedir(d); warnx("directory listing ok (FS mounted and readable)"); } else { /* failed opening dir */ warnx("FAILED LISTING MICROSD ROOT DIRECTORY"); if (stat(cmd_filename, &buffer) == OK) { (void)unlink(cmd_filename); } return 1; } /* read current test status from file, write test instructions for next round */ /* initial values */ int it_left_fsync = fsync_tries; int it_left_abort = abort_tries; int cmd_fd; if (stat(cmd_filename, &buffer) == OK) { /* command file exists, read off state */ cmd_fd = open(cmd_filename, O_RDWR | O_NONBLOCK); char buf[64]; int ret = read(cmd_fd, buf, sizeof(buf)); if (ret > 0) { int count = 0; ret = sscanf(buf, "TEST: %u %u %n", &it_left_fsync, &it_left_abort, &count); } else { buf[0] = '\0'; } if (it_left_fsync > fsync_tries) { it_left_fsync = fsync_tries; } if (it_left_abort > abort_tries) { it_left_abort = abort_tries; } warnx("Iterations left: #%d / #%d of %d / %d\n(%s)", it_left_fsync, it_left_abort, fsync_tries, abort_tries, buf); int it_left_fsync_prev = it_left_fsync; /* now write again what to do next */ if (it_left_fsync > 0) { it_left_fsync--; } if (it_left_fsync == 0 && it_left_abort > 0) { it_left_abort--; /* announce mode switch */ if (it_left_fsync_prev != it_left_fsync && it_left_fsync == 0) { warnx("\n SUCCESSFULLY PASSED FSYNC'ED WRITES, CONTINUTING WITHOUT FSYNC"); fsync(fileno(stdout)); fsync(fileno(stderr)); usleep(20000); } } if (it_left_abort == 0) { (void)unlink(cmd_filename); return 0; } } else { /* this must be the first iteration, do something */ cmd_fd = open(cmd_filename, O_TRUNC | O_WRONLY | O_CREAT); warnx("First iteration of file test\n"); } char buf[64]; (void)sprintf(buf, "TEST: %d %d ", it_left_fsync, it_left_abort); lseek(cmd_fd, 0, SEEK_SET); write(cmd_fd, buf, strlen(buf) + 1); fsync(cmd_fd); /* perform tests for a range of chunk sizes */ unsigned chunk_sizes[] = {32, 64, 128, 256, 512, 600, 1200}; for (unsigned c = 0; c < (sizeof(chunk_sizes) / sizeof(chunk_sizes[0])); c++) { printf("\n\n====== FILE TEST: %u bytes chunks (%s) ======\n", chunk_sizes[c], (it_left_fsync > 0) ? "FSYNC" : "NO FSYNC"); printf("unpower the system immediately (within 0.5s) when the hash (#) sign appears\n"); fsync(fileno(stdout)); fsync(fileno(stderr)); usleep(50000); for (unsigned a = 0; a < alignments; a++) { printf("."); uint8_t write_buf[chunk_sizes[c] + alignments] __attribute__((aligned(64))); /* fill write buffer with known values */ for (unsigned i = 0; i < sizeof(write_buf); i++) { /* this will wrap, but we just need a known value with spacing */ write_buf[i] = i + 11; } uint8_t read_buf[chunk_sizes[c] + alignments] __attribute__((aligned(64))); int fd = open("/fs/microsd/testfile", O_TRUNC | O_WRONLY | O_CREAT); for (unsigned i = 0; i < iterations; i++) { int wret = write(fd, write_buf + a, chunk_sizes[c]); if (wret != (int)chunk_sizes[c]) { warn("WRITE ERROR!"); if ((0x3 & (uintptr_t)(write_buf + a))) { warnx("memory is unaligned, align shift: %d", a); } return 1; } if (it_left_fsync > 0) { fsync(fd); } else { printf("#"); fsync(fileno(stdout)); fsync(fileno(stderr)); } } if (it_left_fsync > 0) { printf("#"); } printf("."); fsync(fileno(stdout)); fsync(fileno(stderr)); usleep(200000); close(fd); fd = open("/fs/microsd/testfile", O_RDONLY); /* read back data for validation */ for (unsigned i = 0; i < iterations; i++) { int rret = read(fd, read_buf, chunk_sizes[c]); if (rret != (int)chunk_sizes[c]) { warnx("READ ERROR!"); return 1; } /* compare value */ bool compare_ok = true; for (unsigned j = 0; j < chunk_sizes[c]; j++) { if (read_buf[j] != write_buf[j + a]) { warnx("COMPARISON ERROR: byte %d, align shift: %d", j, a); compare_ok = false; break; } } if (!compare_ok) { warnx("ABORTING FURTHER COMPARISON DUE TO ERROR"); return 1; } } int ret = unlink("/fs/microsd/testfile"); close(fd); if (ret) { warnx("UNLINKING FILE FAILED"); return 1; } } } fsync(fileno(stdout)); fsync(fileno(stderr)); usleep(20000); /* we always reboot for the next test if we get here */ warnx("Iteration done, rebooting.."); fsync(fileno(stdout)); fsync(fileno(stderr)); usleep(50000); px4_systemreset(false); /* never going to get here */ return 0; }
int deliver(int fd, char *name, int lockfile) { struct stat sb, fsb; struct passwd *pw; int mbfd=-1, rval=1, lfd=-1; char biffmsg[100], buf[8*1024], path[MAXPATHLEN]; off_t curoff; size_t off; ssize_t nr, nw; /* * Disallow delivery to unknown names -- special mailboxes can be * handled in the sendmail aliases file. */ if (!(pw = getpwnam(name))) { merr(NOTFATAL, "unknown name: %s", name); return(1); } (void)snprintf(path, sizeof path, "%s/%s", _PATH_MAILDIR, name); if (lockfile) { lfd = getlock(name, pw); if (lfd == -1) return (1); } /* after this point, always exit via bad to remove lockfile */ retry: if (lstat(path, &sb)) { if (errno != ENOENT) { merr(NOTFATAL, "%s: %s", path, strerror(errno)); goto bad; } if ((mbfd = open(path, O_APPEND|O_CREAT|O_EXCL|O_WRONLY|O_EXLOCK, S_IRUSR|S_IWUSR)) < 0) { if (errno == EEXIST) { /* file appeared since lstat */ goto retry; } else { merr(NOTFATAL, "%s: %s", path, strerror(errno)); goto bad; } } /* * Set the owner and group. Historically, binmail repeated * this at each mail delivery. We no longer do this, assuming * that if the ownership or permissions were changed there * was a reason for doing so. */ if (fchown(mbfd, pw->pw_uid, pw->pw_gid) < 0) { merr(NOTFATAL, "chown %u:%u: %s", pw->pw_uid, pw->pw_gid, name); goto bad; } } else { if (sb.st_nlink != 1 || !S_ISREG(sb.st_mode)) { merr(NOTFATAL, "%s: linked or special file", path); goto bad; } if ((mbfd = open(path, O_APPEND|O_WRONLY|O_EXLOCK, S_IRUSR|S_IWUSR)) < 0) { merr(NOTFATAL, "%s: %s", path, strerror(errno)); goto bad; } if (fstat(mbfd, &fsb)) { /* relating error to path may be bad style */ merr(NOTFATAL, "%s: %s", path, strerror(errno)); goto bad; } if (sb.st_dev != fsb.st_dev || sb.st_ino != fsb.st_ino) { merr(NOTFATAL, "%s: changed after open", path); goto bad; } /* paranoia? */ if (fsb.st_nlink != 1 || !S_ISREG(fsb.st_mode)) { merr(NOTFATAL, "%s: linked or special file", path); goto bad; } } curoff = lseek(mbfd, 0, SEEK_END); (void)snprintf(biffmsg, sizeof biffmsg, "%s@%qd\n", name, curoff); if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { merr(NOTFATAL, "temporary file: %s", strerror(errno)); goto bad; } while ((nr = read(fd, buf, sizeof(buf))) > 0) for (off = 0; off < nr; off += nw) if ((nw = write(mbfd, buf + off, nr - off)) < 0) { merr(NOTFATAL, "%s: %s", path, strerror(errno)); (void)ftruncate(mbfd, curoff); goto bad; } if (nr == 0) { rval = 0; } else { (void)ftruncate(mbfd, curoff); merr(FATAL, "temporary file: %s", strerror(errno)); } bad: if (lfd != -1) { rellock(); close(lfd); } if (mbfd != -1) { (void)fsync(mbfd); /* Don't wait for update. */ (void)close(mbfd); /* Implicit unlock. */ } if (!rval) notifybiff(biffmsg); return(rval); }
void write_perf_test1(off64_t kilo64,long long reclen ,long long *data1,long long *data2) { double starttime1; double writetime[2]; double walltime[2], cputime[2]; double qtime_start,qtime_stop; double hist_time; double compute_val = (double)0; long long i,j; off64_t numrecs64,traj_offset; off64_t lock_offset=0; long long Index = 0; long long file_flags = 0; long long traj_size; unsigned long long writerate[2]; off64_t filebytes64; int ltest; char *maddr; char *wmaddr,*free_addr; char *pbuff; char *nbuff; int fd,wval; int notruncate = 1; unsigned long w_traj_ops_completed=0; unsigned long w_traj_bytes_completed=0; char *filename = "/mnt/ramdisk/test1"; int test_foo; nbuff=wmaddr=free_addr=0; traj_offset=0; test_foo=0; hist_time=qtime_start=qtime_stop=0; maddr=0; pbuff=mainbuffer; numrecs64 = (kilo64*1024)/reclen; filebytes64 = numrecs64*reclen; fd = 0; file_flags = O_RDWR; /* Sanity check */ /* Some filesystems do not behave correctly and fail * when this sequence is performned. This is a very * bad thing. It breaks many applications and lurks * around quietly. This code should never get * triggered, but in the case of running iozone on * an NFS client, the filesystem type on the server * that is being exported can cause this failure. * If this failure happens, then the NFS client is * going to going to have problems, but the acutal * problem is the filesystem on the NFS server. * It's not NFS, it's the local filesystem on the * NFS server that is not correctly permitting * the sequence to function. */ /* _SUA_ Services for Unix Applications, under Windows does not have a truncate, so this must be skipped */ if((fd = open(filename, (int)O_CREAT|O_RDWR,0))<0) { printf("\nCan not open temp file: %s\n", filename); perror("open"); exit(44); } if(!notruncate) { wval=ftruncate(fd,0); if(wval < 0) { printf("\n\nSanity check failed. Do not deploy this filesystem in a production environment !\n"); exit(44); } close(fd); } /* Sanity check */ ltest=3; for( j=0; j<ltest; j++) { if(j==0) { if(!notruncate) { if((fd = creat(filename, 0640))<0) { printf("\nCan not create temp file: %s\n", filename); perror("creat"); exit(42); } } } if(fd) close(fd); if((fd = open(filename, (int)file_flags,0))<0) { printf("\nCan not open temp file: %s\n", filename); perror("open"); exit(44); } wval=fsync(fd); if(wval==-1){ perror("fsync"); } pbuff=mainbuffer; starttime1 = time_so_far(); compute_val=(double)0; w_traj_ops_completed=0; w_traj_bytes_completed=0; for(i=0; i<numrecs64; i++){ wval=write(fd, pbuff, (size_t ) reclen); if(wval != reclen) { #ifdef NO_PRINT_LLD printf("\nError writing block %ld, fd= %d\n", i, fd); #else printf("\nError writing block %lld, fd= %d\n", i, fd); #endif if(wval == -1) perror("write"); } w_traj_ops_completed++; w_traj_bytes_completed+=reclen; } writetime[j] = ((time_so_far() - starttime1)) -compute_val; if(writetime[j] < (double).000001) { writetime[j]=(double).000001; } wval=close(fd); if(wval==-1){ perror("close"); } } filebytes64=w_traj_bytes_completed; for(j=0;j<ltest;j++) { writerate[j] = (unsigned long long) ((double) filebytes64 / writetime[j]); printf("%s: ltest %d writerate %llu\n", __func__, j, writerate[j]); } }
pid_t cyon_store_write(void) { pid_t pid; u_int8_t *buf; struct store_header header; int fd, ret; u_int32_t len, blen; u_char hash[SHA_DIGEST_LENGTH]; char fpath[MAXPATHLEN], tpath[MAXPATHLEN]; if (rnode == NULL || store_modified == 0 || store_nopersist) { cyon_log(LOG_NOTICE, "store is clean, not writing"); return (CYON_RESULT_OK); } /* * The write lock protects us from getting new entries in the log * so it is safe to reopen the logs after the fork. */ cyon_store_lock(1); pid = fork(); if (pid == -1) { cyon_store_unlock(); cyon_log(LOG_NOTICE, "store write not started (fork: %s)", errno_s); return (CYON_RESULT_ERROR); } if (pid != 0) { store_modified = 0; if (!cyon_readonly_mode) cyon_storelog_reopen(1); cyon_store_unlock(); cyon_log(LOG_NOTICE, "store write started (%d)", pid); return (pid); } if (!cyon_readonly_mode) close(lfd); snprintf(fpath, sizeof(fpath), CYON_STORE_FILE, storepath, storename); snprintf(tpath, sizeof(tpath), CYON_STORE_TMPFILE, storepath, storename); fd = open(tpath, O_CREAT | O_TRUNC | O_WRONLY, 0700); if (fd == -1) fatal("open(%s): %s", tpath, errno_s); memset(&header, 0, sizeof(header)); if (store_passphrase != NULL) header.flags |= STORE_HAS_PASSPHRASE; len = 0; blen = 128 * 1024 * 1024; buf = cyon_malloc(blen); memcpy(buf, &header, sizeof(header)); len += sizeof(header); if (header.flags & STORE_HAS_PASSPHRASE) { memcpy(buf + len, store_passphrase, SHA256_DIGEST_LENGTH); len += SHA256_DIGEST_LENGTH; } SHA_Init(&shactx); cyon_store_writenode(fd, rnode, buf, blen, &len, NULL); if (len > 0) cyon_atomic_write(fd, buf, len, &shactx); cyon_mem_free(buf); SHA_Final(hash, &shactx); cyon_atomic_write(fd, hash, SHA_DIGEST_LENGTH, NULL); for (;;) { ret = fsync(fd); if (ret == -1 && errno == EINTR) continue; if (ret == -1) fatal("store write failed %s", errno_s); break; } close(fd); if (rename(tpath, fpath) == -1) fatal("cannot move store into place: %s", errno_s); exit(0); }
/* Read the request from a client socket. */ int fetch_request(t_session *session) { char *new_reqbuf, *strstart, *strend; long max_request_size, bytes_read, header_length = -1, content_length = -1; int result = 200, write_bytes, poll_result; time_t deadline; struct pollfd poll_data; bool keep_reading = true, store_on_disk = false; int upload_handle = -1; if (session->request_limit == false) { deadline = session->time + NO_REQUEST_LIMIT_TIME; max_request_size = NO_REQUEST_LIMIT_SIZE; } else if (session->kept_alive == 0) { deadline = session->time + session->binding->time_for_1st_request; max_request_size = session->binding->max_request_size; } else { deadline = session->time + session->binding->time_for_request; max_request_size = session->binding->max_request_size; } do { /* Check if requestbuffer contains a complete request. */ if (session->request != NULL) { if (header_length == -1) { if ((strstart = strstr(session->request, "\r\n\r\n")) != NULL) { *(strstart + 2) = '\0'; header_length = strstart + 4 - session->request; session->header_length = header_length; determine_request_method(session); store_on_disk = (session->request_method == PUT) && session->binding->enable_alter; if (store_on_disk) { if ((session->uploaded_file = (char*)malloc(session->config->upload_directory_len + 15)) != NULL) { strcpy(session->uploaded_file, session->config->upload_directory); strcpy(session->uploaded_file + session->config->upload_directory_len, "/upload_XXXXXX"); if ((upload_handle = mkstemp(session->uploaded_file)) == -1) { free(session->uploaded_file); session->uploaded_file = NULL; } } if (session->uploaded_file == NULL) { log_error(session, "can't create temporary file for PUT request"); result = 500; break; } session->uploaded_size = session->bytes_in_buffer - header_length; if (write_buffer(upload_handle, session->request + header_length, session->uploaded_size) == -1) { result = 500; break; } session->bytes_in_buffer = header_length; } } } if (header_length != -1) { if (content_length == -1) { if ((strstart = strcasestr(session->request, hs_conlen)) != NULL) { strstart += 16; if ((strend = strstr(strstart, "\r\n")) != NULL) { *strend = '\0'; content_length = str2int(strstart); *strend = '\r'; if ((content_length < 0) || (INT_MAX - content_length - 2 <= header_length)) { result = 500; break; } if (store_on_disk) { /* Write to file on disk */ session->content_length = 0; if (content_length > session->binding->max_upload_size) { result = 413; break; } session->buffer_size = header_length + REQUEST_BUFFER_CHUNK; if ((new_reqbuf = (char*)realloc(session->request, session->buffer_size + 1)) != NULL) { session->request = new_reqbuf; } else { session->error_cause = ec_SOCKET_READ_ERROR; result = -1; break; } } else { /* Read into memory */ session->content_length = content_length; if (header_length + content_length > max_request_size) { session->error_cause = ec_MAX_REQUESTSIZE; result = -1; break; } if (header_length + content_length > session->buffer_size) { session->buffer_size = header_length + content_length; if ((new_reqbuf = (char*)realloc(session->request, session->buffer_size + 1)) != NULL) { session->request = new_reqbuf; } else { session->error_cause = ec_SOCKET_READ_ERROR; result = -1; break; } } } } } else { session->content_length = 0; if (store_on_disk) { result = 411; } break; } } if (content_length > -1) { if (store_on_disk) { if (session->uploaded_size == content_length) { /* Received a complete PUT request */ break; } } else { if (session->bytes_in_buffer >= header_length + content_length) { /* Received a complete request */ break; } } } } } #ifdef ENABLE_SSL poll_result = session->binding->use_ssl ? ssl_pending(&(session->ssl_context)) : 0; if (poll_result == 0) { #endif poll_data.fd = session->client_socket; poll_data.events = POLL_EVENT_BITS; poll_result = poll(&poll_data, 1, 1000); #ifdef ENABLE_SSL } #endif switch (poll_result) { case -1: if (errno != EINTR) { session->error_cause = ec_SOCKET_READ_ERROR; result = -1; keep_reading = false; } break; case 0: if (session->force_quit) { session->error_cause = ec_FORCE_QUIT; result = -1; keep_reading = false; } else if (time(NULL) > deadline) { session->error_cause = ec_TIMEOUT; result = -1; keep_reading = false; } break; default: if ((content_length == -1) && ((session->buffer_size - session->bytes_in_buffer) < 256)) { session->buffer_size += REQUEST_BUFFER_CHUNK; if ((new_reqbuf = (char*)realloc(session->request, session->buffer_size + 1)) != NULL) { session->request = new_reqbuf; } else { session->error_cause = ec_SOCKET_READ_ERROR; result = -1; keep_reading = false; break; } } /* Read from socket. */ #ifdef ENABLE_SSL if (session->binding->use_ssl) { bytes_read = ssl_receive(&(session->ssl_context), session->request + session->bytes_in_buffer, session->buffer_size - session->bytes_in_buffer); } else #endif bytes_read = recv(session->client_socket, session->request + session->bytes_in_buffer, session->buffer_size - session->bytes_in_buffer, 0); switch (bytes_read) { case -1: if (errno != EINTR) { session->error_cause = ec_SOCKET_READ_ERROR; result = -1; keep_reading = false; } break; case 0: session->error_cause = ec_CLIENT_DISCONNECTED; result = -1; keep_reading = false; break; default: if (store_on_disk) { /* Write to file on disk */ write_bytes = bytes_read; if (session->uploaded_size + bytes_read > content_length) { write_bytes -= ((session->uploaded_size + bytes_read) - content_length); } if (write_buffer(upload_handle, session->request + header_length, write_bytes) == -1) { result = 500; keep_reading = false; break; } if ((session->uploaded_size += write_bytes) > session->binding->max_upload_size) { keep_reading = false; result = 413; break; } if (write_bytes < bytes_read) { memmove(session->request + header_length, session->request + header_length + write_bytes, bytes_read - write_bytes); session->bytes_in_buffer += bytes_read - write_bytes; keep_reading = false; } } else { /* Read into memory */ session->bytes_in_buffer += bytes_read; *(session->request + session->bytes_in_buffer) = '\0'; if (session->bytes_in_buffer > max_request_size) { keep_reading = false; session->error_cause = ec_MAX_REQUESTSIZE; result = -1; break; } } } } } while (keep_reading); if (upload_handle != -1) { fsync(upload_handle); close(upload_handle); } #ifdef ENABLE_TOMAHAWK increment_transfer(TRANSFER_RECEIVED, header_length + content_length); #endif return result; }
void gds_rundown(void) { boolean_t cancelled_dbsync_timer, cancelled_timer, have_standalone_access, ipc_deleted, skip_database_rundown; boolean_t is_cur_process_ss_initiator, remove_shm, vermismatch, we_are_last_user, we_are_last_writer, is_mm; now_t now; /* for GET_CUR_TIME macro */ char *time_ptr, time_str[CTIME_BEFORE_NL + 2]; /* for GET_CUR_TIME macro */ gd_region *reg; int save_errno, status, rc; int4 semval, ftok_semval, sopcnt, ftok_sopcnt; short crash_count; sm_long_t munmap_len; sgmnt_addrs *csa; sgmnt_data_ptr_t csd; struct shmid_ds shm_buf; struct sembuf sop[2], ftok_sop[2]; uint4 jnl_status; unix_db_info *udi; jnl_private_control *jpc; jnl_buffer_ptr_t jbp; shm_snapshot_t *ss_shm_ptr; uint4 ss_pid, onln_rlbk_pid, holder_pid; boolean_t was_crit; jnl_status = 0; reg = gv_cur_region; /* Local copy */ /* early out for cluster regions * to avoid tripping the assert below. * Note: * This early out is consistent with VMS. It has been * noted that all of the gtcm assignments * to gv_cur_region should use the TP_CHANGE_REG * macro. This would also avoid the assert problem * and should be done eventually. */ if (dba_cm == reg->dyn.addr->acc_meth) return; udi = FILE_INFO(reg); csa = &udi->s_addrs; csd = csa->hdr; assert(csa == cs_addrs && csd == cs_data); if ((reg->open) && (dba_usr == csd->acc_meth)) { change_reg(); gvusr_rundown(); return; } ESTABLISH(gds_rundown_ch); assert(reg->open); /* if we failed to open, dbinit_ch should have taken care of proper clean up */ assert(!reg->opening); /* see comment above */ switch(csd->acc_meth) { /* Pass mm and bg through */ case dba_bg: is_mm = FALSE; break; case dba_mm: is_mm = TRUE; break; case dba_usr: assert(FALSE); default: REVERT; return; } assert(!csa->hold_onto_crit || (csa->now_crit && jgbl.onlnrlbk)); /* If we are online rollback, we should already be holding crit and should release it only at the end of this module. This * is usually done by noting down csa->now_crit in a local variable (was_crit) and using it whenever we are about to * grab_crit. But, there are instances (like mupip_set_journal.c) where we grab_crit but invoke gds_rundown without any * preceeding rel_crit. Such code relies on the fact that gds_rundown does rel_crit unconditionally (to get locks to a known * state). So, augment csa->now_crit with jgbl.onlnrlbk to track if we can rel_crit unconditionally or not in gds_rundown. */ was_crit = (csa->now_crit && jgbl.onlnrlbk); /* Cancel any pending flush timer for this region by this task */ cancelled_timer = FALSE; cancelled_dbsync_timer = FALSE; CANCEL_DB_TIMERS(reg, csa, cancelled_timer, cancelled_dbsync_timer); we_are_last_user = FALSE; if (!csa->persistent_freeze) region_freeze(reg, FALSE, FALSE, FALSE); if (!was_crit) { rel_crit(reg); /* get locks to known state */ mutex_cleanup(reg); } DEFER_INTERRUPTS(INTRPT_IN_GDS_RUNDOWN); /* If the process has standalone access, it has udi->grabbed_access_sem set to TRUE at this point. Note that down * in a local variable as the udi->grabbed_access_sem is set to TRUE even for non-standalone access below and hence * we can't rely on that later to determine if the process had standalone access or not when it entered this function. * We need to guarantee that none else access database file header when semid/shmid fields are reset. * We already have created ftok semaphore in db_init or, mu_rndwn_file and did not remove it. * So just lock it. We do it in blocking mode. */ have_standalone_access = udi->grabbed_access_sem; /* process holds standalone access */ /* The only process that can invoke gds_rundown while holding access control semaphore is RECOVER/ROLLBACK. All the others * (like MUPIP SET -FILE/MUPIP EXTEND would have invoked db_ipcs_reset() before invoking gds_rundown (from * mupip_exit_handler). The only exception is when these processes encounter a terminate signal and they reach * mupip_exit_handler while holding access control semaphore. Assert accordingly. */ assert(!have_standalone_access || mupip_jnl_recover || process_exiting); /* If we have standalone access, then ensure that a concurrent online rollback cannot be running at the same time as it * needs the access control lock as well. The only expection is we are online rollback and currently running down. */ onln_rlbk_pid = csa->nl->onln_rlbk_pid; assert(!have_standalone_access || mupip_jnl_recover || !onln_rlbk_pid || !is_proc_alive(onln_rlbk_pid, 0)); skip_database_rundown = FALSE; if (!have_standalone_access) { /* We need to guarantee that no one else access database file header when semid/shmid fields are reset. * We already have created ftok semaphore in db_init or mu_rndwn_file and did not remove it. So just * lock it. We do it in blocking mode. */ if (!ftok_sem_lock(reg, FALSE, FALSE)) rts_error(VARLSTCNT(4) ERR_DBFILERR, 2, DB_LEN_STR(reg)); FTOK_TRACE(csa, csa->ti->curr_tn, ftok_ops_lock, process_id); sop[0].sem_num = 0; sop[0].sem_op = 0; /* Wait for 0 */ sop[1].sem_num = 0; sop[1].sem_op = 1; /* Lock */ sopcnt = 2; sop[0].sem_flg = sop[1].sem_flg = SEM_UNDO | IPC_NOWAIT; /* Don't wait the first time thru */ SEMOP(udi->semid, sop, sopcnt, status, NO_WAIT); if (-1 == status) /* We couldn't get it in one shot -- see if we already have it */ { save_errno = errno; holder_pid = semctl(udi->semid, 0, GETPID); if (holder_pid == process_id) { send_msg(VARLSTCNT(5) MAKE_MSG_INFO(ERR_CRITSEMFAIL), 2, DB_LEN_STR(reg), ERR_RNDWNSEMFAIL); REVERT; ENABLE_INTERRUPTS(INTRPT_IN_GDS_RUNDOWN); return; /* Already in rundown for this region */ } if (EAGAIN != save_errno) { assert(FALSE); rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown first semop/semctl"), save_errno); } /* Before attempting again in the blocking mode, see if the holding process is an online rollback. * If so, it is likely we won't get the access control semaphore anytime soon. In that case, we * are better off skipping rundown and continuing with sanity cleanup and exit. */ skip_database_rundown = (onln_rlbk_pid || csd->file_corrupt); if (!skip_database_rundown) { sop[0].sem_flg = sop[1].sem_flg = SEM_UNDO; /* Try again - blocking this time */ SEMOP(udi->semid, sop, 2, status, FORCED_WAIT); if (-1 == status) /* We couldn't get it at all.. */ rts_error(VARLSTCNT(5) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), errno); } } udi->grabbed_access_sem = !skip_database_rundown; } /* else we we hold the access control semaphore and therefore have standalone access. We do not release it now - we * release it later in mupip_exit_handler.c. Since we already hold the access control semaphore, we don't need the * ftok semaphore and trying it could cause deadlock */ /* At this point we are guaranteed no one else is doing a db_init/rundown as we hold the access control semaphore */ assert(csa->ref_cnt); /* decrement private ref_cnt before shared ref_cnt decrement. */ csa->ref_cnt--; /* Currently journaling logic in gds_rundown() in VMS relies on this order to detect last writer */ assert(!csa->ref_cnt); --csa->nl->ref_cnt; if (memcmp(csa->nl->now_running, gtm_release_name, gtm_release_name_len + 1)) { /* VERMISMATCH condition. Possible only if DSE */ assert(dse_running); vermismatch = TRUE; } else vermismatch = FALSE; if (-1 == shmctl(udi->shmid, IPC_STAT, &shm_buf)) { save_errno = errno; rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown shmctl"), save_errno); } else we_are_last_user = (1 == shm_buf.shm_nattch) && !vermismatch; assert(!have_standalone_access || we_are_last_user || jgbl.onlnrlbk); /* recover => one user except ONLINE ROLLBACK */ if (-1 == (semval = semctl(udi->semid, 1, GETVAL))) rts_error(VARLSTCNT(5) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), errno); we_are_last_writer = (1 == semval) && (FALSE == reg->read_only) && !vermismatch;/* There's one writer left and I am it */ assert(!we_are_last_writer || !skip_database_rundown); assert(!we_are_last_user || !skip_database_rundown); assert(!(have_standalone_access && !reg->read_only) || we_are_last_writer || jgbl.onlnrlbk); /* recover + R/W region => one writer except ONLINE ROLLBACK */ if (!have_standalone_access && (-1 == (ftok_semval = semctl(udi->ftok_semid, 1, GETVAL)))) rts_error(VARLSTCNT(5) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), errno); if (NULL != csa->ss_ctx) ss_destroy_context(csa->ss_ctx); /* SS_MULTI: If multiple snapshots are supported, then we have to run through each of the snapshots */ assert(1 == MAX_SNAPSHOTS); ss_shm_ptr = (shm_snapshot_ptr_t)SS_GETSTARTPTR(csa); ss_pid = ss_shm_ptr->ss_info.ss_pid; is_cur_process_ss_initiator = (process_id == ss_pid); if (ss_pid && (is_cur_process_ss_initiator || we_are_last_user)) { /* Try getting snapshot crit latch. If we don't get latch, we won't hang for eternity and will skip * doing the orphaned snapshot cleanup. It will be cleaned up eventually either by subsequent MUPIP * INTEG or by a MUPIP RUNDOWN. */ if (ss_get_lock_nowait(reg) && (ss_pid == ss_shm_ptr->ss_info.ss_pid) && (is_cur_process_ss_initiator || !is_proc_alive(ss_pid, 0))) { ss_release(NULL); ss_release_lock(reg); } } /* If csa->nl->donotflush_dbjnl is set, it means mupip recover/rollback was interrupted and therefore we need not flush * shared memory contents to disk as they might be in an inconsistent state. Moreover, any more flushing will only cause * future rollback to undo more journal records (PBLKs). In this case, we will go ahead and remove shared memory (without * flushing the contents) in this routine. A reissue of the recover/rollback command will restore the database to a * consistent state. */ if (!csa->nl->donotflush_dbjnl && !reg->read_only && !vermismatch) { /* If we had an orphaned block and were interrupted, set wc_blocked so we can invoke wcs_recover. Do it ONLY * if there is NO concurrent online rollback running (as we need crit to set wc_blocked) */ if (csa->wbuf_dqd) { /* If we had an orphaned block and were interrupted, mupip_exit_handler will invoke secshr_db_clnup which * will clear this field and so we should never come to gds_rundown with a non-zero wbuf_dqd. The only * exception is if we are recover/rollback in which case gds_rundown (from mur_close_files) is invoked * BEFORE secshr_db_clnup in mur_close_files. * Note: It is NOT possible for online rollback to reach here with wbuf_dqd being non-zero. This is because * the moment we apply the first PBLK, we stop all interrupts and hence can never be interrupted in * wcs_wtstart or wcs_get_space. Assert accordingly. */ assert(mupip_jnl_recover && !jgbl.onlnrlbk && !skip_database_rundown); if (!was_crit) grab_crit(reg); SET_TRACEABLE_VAR(csd->wc_blocked, TRUE); BG_TRACE_PRO_ANY(csa, wcb_gds_rundown); send_msg(VARLSTCNT(8) ERR_WCBLOCKED, 6, LEN_AND_LIT("wcb_gds_rundown"), process_id, &csa->ti->curr_tn, DB_LEN_STR(reg)); csa->wbuf_dqd = 0; wcs_recover(reg); if (is_mm) { assert(FALSE); csd = csa->hdr; } BG_TRACE_PRO_ANY(csa, lost_block_recovery); if (!was_crit) rel_crit(reg); } if (JNL_ENABLED(csd) && IS_GTCM_GNP_SERVER_IMAGE) originator_prc_vec = NULL; /* If we are the last writing user, then everything must be flushed */ if (we_are_last_writer) { /* Time to flush out all of our buffers */ if (is_mm) { if (csa->total_blks != csa->ti->total_blks) /* do remap if file had been extended */ { if (!was_crit) grab_crit(reg); wcs_mm_recover(reg); csd = csa->hdr; if (!was_crit) rel_crit(reg); } csa->nl->remove_shm = TRUE; } if (csd->wc_blocked && jgbl.onlnrlbk) { /* if the last update done by online rollback was not committed in the normal code-path but was * completed by secshr_db_clnup, wc_blocked will be set to TRUE. But, since online rollback never * invokes grab_crit (since csa->hold_onto_crit is set to TRUE), wcs_recover is never invoked. This * could result in the last update never getting flushed to the disk and if online rollback happened * to be the last writer then the shared memory will be flushed and removed and the last update will * be lost. So, force wcs_recover if we find ourselves in such a situation. But, wc_blocked is * possible only if phase1 or phase2 errors are induced using white box test cases */ assert(WB_COMMIT_ERR_ENABLED); wcs_recover(reg); } /* Note WCSFLU_SYNC_EPOCH ensures the epoch is synced to the journal and indirectly * also ensures that the db is fsynced. We don't want to use it in the calls to * wcs_flu() from t_end() and tp_tend() since we can defer it to out-of-crit there. * In this case, since we are running down, we don't have any such option. */ csa->nl->remove_shm = wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH); /* Since we_are_last_writer, we should be guaranteed that wcs_flu() did not change csd, (in * case of MM for potential file extension), even if it did a grab_crit(). Therefore, make * sure that's true. */ assert(csd == csa->hdr); assert(0 == memcmp(csd->label, GDS_LABEL, GDS_LABEL_SZ - 1)); } else if (((cancelled_timer && (0 > csa->nl->wcs_timers)) || cancelled_dbsync_timer) && !skip_database_rundown) { /* cancelled pending db or jnl flush timers - flush database and journal buffers to disk */ if (!was_crit) grab_crit(reg); /* we need to sync the epoch as the fact that there is no active pending flush timer implies * there will be noone else who will flush the dirty buffers and EPOCH to disk in a timely fashion */ wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH | WCSFLU_SYNC_EPOCH); if (!was_crit) rel_crit(reg); assert((dba_mm == cs_data->acc_meth) || (csd == cs_data)); csd = cs_data; /* In case this is MM and wcs_flu() remapped an extended database, reset csd */ } /* Do rundown journal processing after buffer flushes since they require jnl to be open */ if (JNL_ENABLED(csd)) { /* the following tp_change_reg() is not needed due to the assert csa == cs_addrs at the beginning * of gds_rundown(), but just to be safe. To be removed by 2002!! --- nars -- 2001/04/25. */ tp_change_reg(); /* call this because jnl_ensure_open checks cs_addrs rather than gv_cur_region */ jpc = csa->jnl; jbp = jpc->jnl_buff; if (jbp->fsync_in_prog_latch.u.parts.latch_pid == process_id) { assert(FALSE); COMPSWAP_UNLOCK(&jbp->fsync_in_prog_latch, process_id, 0, LOCK_AVAILABLE, 0); } if (jbp->io_in_prog_latch.u.parts.latch_pid == process_id) { assert(FALSE); COMPSWAP_UNLOCK(&jbp->io_in_prog_latch, process_id, 0, LOCK_AVAILABLE, 0); } if ((((NOJNL != jpc->channel) && !JNL_FILE_SWITCHED(jpc)) || we_are_last_writer && (0 != csa->nl->jnl_file.u.inode)) && !skip_database_rundown) { /* We need to close the journal file cleanly if we have the latest generation journal file open * or if we are the last writer and the journal file is open in shared memory (not necessarily * by ourselves e.g. the only process that opened the journal got shot abnormally) * Note: we should not infer anything from the shared memory value of csa->nl->jnl_file.u.inode * if we are not the last writer as it can be concurrently updated. */ if (!was_crit) grab_crit(reg); if (JNL_ENABLED(csd)) { SET_GBL_JREC_TIME; /* jnl_ensure_open/jnl_put_jrt_pini/pfin/jnl_file_close all need it */ /* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order * of jnl records. This needs to be done BEFORE the jnl_ensure_open as that could write * journal records (if it decides to switch to a new journal file). */ ADJUST_GBL_JREC_TIME(jgbl, jbp); jnl_status = jnl_ensure_open(); if (0 == jnl_status) { /* If we_are_last_writer, we would have already done a wcs_flu() which would * have written an epoch record and we are guaranteed no further updates * since we are the last writer. So, just close the journal. * Although we assert pini_addr should be non-zero for last_writer, we * play it safe in PRO and write a PINI record if not written already. */ assert(!jbp->before_images || is_mm || !we_are_last_writer || 0 != jpc->pini_addr); if (we_are_last_writer && 0 == jpc->pini_addr) jnl_put_jrt_pini(csa); if (0 != jpc->pini_addr) jnl_put_jrt_pfin(csa); /* If not the last writer and no pending flush timer left, do jnl flush now */ if (!we_are_last_writer && (0 > csa->nl->wcs_timers)) { if (SS_NORMAL == (jnl_status = jnl_flush(reg))) { assert(jbp->freeaddr == jbp->dskaddr); jnl_fsync(reg, jbp->dskaddr); assert(jbp->fsync_dskaddr == jbp->dskaddr); } else { send_msg(VARLSTCNT(9) ERR_JNLFLUSH, 2, JNL_LEN_STR(csd), ERR_TEXT, 2, RTS_ERROR_TEXT("Error with journal flush in gds_rundown"), jnl_status); assert(NOJNL == jpc->channel);/* jnl file lost has been triggered */ /* In this routine, all code that follows from here on does not * assume anything about the journaling characteristics of this * database so it is safe to continue execution even though * journaling got closed in the middle. */ } } jnl_file_close(reg, we_are_last_writer, FALSE); } else send_msg(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(csd), DB_LEN_STR(reg)); } if (!was_crit) rel_crit(reg); } } if (we_are_last_writer) /* Flush the fileheader last and harden the file to disk */ { if (!was_crit) grab_crit(reg); /* To satisfy crit requirement in fileheader_sync() */ memset(csd->machine_name, 0, MAX_MCNAMELEN); /* clear the machine_name field */ if (!have_standalone_access && we_are_last_user) { /* mupip_exit_handler will do this after mur_close_file */ csd->semid = INVALID_SEMID; csd->shmid = INVALID_SHMID; csd->gt_sem_ctime.ctime = 0; csd->gt_shm_ctime.ctime = 0; } fileheader_sync(reg); if (!was_crit) rel_crit(reg); if (FALSE == is_mm) { if (-1 == fsync(udi->fd)) /* Sync it all */ { rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file sync at close"), errno); } } else { /* Now do final MM file sync before exit */ # if !defined(TARGETED_MSYNC) && !defined(NO_MSYNC) if (-1 == fsync(udi->fd)) /* Sync it all */ { rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file sync at close"), errno); } # else if (-1 == msync((caddr_t)csa->db_addrs[0], (size_t)(csa->db_addrs[1] - csa->db_addrs[0]), MS_SYNC)) { rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("Error during file msync at close"), errno); } # endif } } } /* end if (!reg->read_only && !csa->nl->donotflush_dbjnl) */ /* We had cancelled all db timers at start of rundown. In case as part of rundown (wcs_flu above), we had started * any timers, cancel them BEFORE setting reg->open to FALSE (assert in wcs_clean_dbsync relies on this). */ CANCEL_DB_TIMERS(reg, csa, cancelled_timer, cancelled_dbsync_timer); if (reg->read_only && we_are_last_user && !have_standalone_access) { /* mupip_exit_handler will do this after mur_close_file */ db_ipcs.semid = INVALID_SEMID; db_ipcs.shmid = INVALID_SHMID; db_ipcs.gt_sem_ctime = 0; db_ipcs.gt_shm_ctime = 0; db_ipcs.fn_len = reg->dyn.addr->fname_len; memcpy(db_ipcs.fn, reg->dyn.addr->fname, reg->dyn.addr->fname_len); db_ipcs.fn[reg->dyn.addr->fname_len] = 0; /* request gtmsecshr to flush. read_only cannot flush itself */ if (0 != send_mesg2gtmsecshr(FLUSH_DB_IPCS_INFO, 0, (char *)NULL, 0)) rts_error(VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("gtmsecshr failed to update database file header")); } /* Done with file now, close it */ CLOSEFILE_RESET(udi->fd, rc); /* resets "udi->fd" to FD_INVALID */ if (-1 == rc) { rts_error(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, LEN_AND_LIT("Error during file close"), errno); } /* Unmap storage if mm mode but only the part that is not the fileheader (so shows up in dumps) */ if (is_mm) { munmap_len = (sm_long_t)((csa->db_addrs[1] - csa->db_addrs[0]) - ROUND_UP(SIZEOF_FILE_HDR(csa->hdr), MSYNC_ADDR_INCS)); if (munmap_len > 0) { munmap((caddr_t)(csa->db_addrs[0] + ROUND_UP(SIZEOF_FILE_HDR(csa->hdr), MSYNC_ADDR_INCS)), (size_t)(munmap_len)); # ifdef DEBUG_DB64 rel_mmseg((caddr_t)csa->db_addrs[0]); # endif } } /* If we had skipped flushing journal and database buffers due to a concurrent online rollback, increment the counter * indicating that in the shared memory so that online rollback can report the # of such processes when it shuts down. */ if (skip_database_rundown) /* indicates flushing was skipped */ csa->nl->dbrndwn_skip_cnt++; /* If we are online rollback, report the # of processes that skipped rundown because we were holding the access control * semaphore */ if (jgbl.onlnrlbk && csa->nl->dbrndwn_skip_cnt) { send_msg(VARLSTCNT(3) ERR_RNDWNSKIPCNT, 1, csa->nl->dbrndwn_skip_cnt); csa->nl->dbrndwn_skip_cnt = 0; } /* Detach our shared memory while still under lock so reference counts will be correct for the next process to run down * this region. In the process also get the remove_shm status from node_local before detaching. * If csa->nl->donotflush_dbjnl is TRUE, it means we can safely remove shared memory without compromising data * integrity as a reissue of recover will restore the database to a consistent state. */ remove_shm = !vermismatch && (csa->nl->remove_shm || csa->nl->donotflush_dbjnl); rel_crit(reg); /* Since we are about to detach from the shared memory, release crit and reset onln_rlbk_pid */ if (jgbl.onlnrlbk) { /* We are done with online rollback on this region Indicate to other processes by setting the onln_rlbk_pid to 0 */ csa->hold_onto_crit = FALSE; csa->nl->onln_rlbk_pid = 0; } status = shmdt((caddr_t)csa->nl); csa->nl = NULL; /* dereferencing nl after detach is not right, so we set it to NULL so that we can test before dereference*/ if (-1 == status) send_msg(VARLSTCNT(9) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, LEN_AND_LIT("Error during shmdt"), errno); REMOVE_CSA_FROM_CSADDRSLIST(csa); /* remove "csa" from list of open regions (cs_addrs_list) */ reg->open = FALSE; /* If file is still not in good shape, die here and now before we get rid of our storage */ assertpro(0 == csa->wbuf_dqd); ipc_deleted = FALSE; /* If we are the very last user, remove shared storage id and the semaphores */ if (we_are_last_user) { /* remove shared storage, only if last writer to rundown did a successful wcs_flu() */ assert(!vermismatch); if (remove_shm) { ipc_deleted = TRUE; if (0 != shm_rmid(udi->shmid)) rts_error(VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove shared memory")); } else if (is_src_server || is_updproc) { gtm_putmsg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id); send_msg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id); } else send_msg(VARLSTCNT(6) ERR_DBRNDWNWRN, 4, DB_LEN_STR(reg), process_id, process_id); /* mupip recover/rollback don't release the semaphore here, but do it later in db_ipcs_reset (invoked from * mur_close_files()) */ if (!have_standalone_access) { if (0 != sem_rmid(udi->semid)) rts_error(VARLSTCNT(8) ERR_DBFILERR, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("Unable to remove semaphore")); udi->grabbed_access_sem = FALSE; } } else { assert(!have_standalone_access || jgbl.onlnrlbk); if (!jgbl.onlnrlbk) { /* If we were writing, get rid of our writer access count semaphore */ if (!reg->read_only) if (0 != (save_errno = do_semop(udi->semid, 1, -1, SEM_UNDO))) rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown write semaphore release"), save_errno); /* Now remove the rundown lock */ if (!skip_database_rundown) { /* Do it only if we skipped getting the access control semaphore above */ if (0 != (save_errno = do_semop(udi->semid, 0, -1, SEM_UNDO))) rts_error(VARLSTCNT(9) ERR_CRITSEMFAIL, 2, DB_LEN_STR(reg), ERR_TEXT, 2, RTS_ERROR_TEXT("gds_rundown rundown semaphore release"), save_errno); udi->grabbed_access_sem = FALSE; } } /* else access control semaphore will be released in db_ipcs_reset */ } if (!have_standalone_access) { if (!ftok_sem_release(reg, !have_standalone_access, FALSE)) rts_error(VARLSTCNT(4) ERR_DBFILERR, 2, DB_LEN_STR(reg)); FTOK_TRACE(csa, csa->ti->curr_tn, ftok_ops_release, process_id); } ENABLE_INTERRUPTS(INTRPT_IN_GDS_RUNDOWN); if (!ipc_deleted) { GET_CUR_TIME; if (is_src_server) gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr, LEN_AND_LIT("Source server"), REG_LEN_STR(reg)); if (is_updproc) gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr, LEN_AND_LIT("Update process"), REG_LEN_STR(reg)); if (mupip_jnl_recover && (!jgbl.onlnrlbk || !we_are_last_user)) { gtm_putmsg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr, LEN_AND_LIT("Mupip journal process"), REG_LEN_STR(reg)); send_msg(VARLSTCNT(8) ERR_IPCNOTDEL, 6, CTIME_BEFORE_NL, time_ptr, LEN_AND_LIT("Mupip journal process"), REG_LEN_STR(reg)); } } REVERT; }
static int copy_file( const char *file, const char *copy) { int fd1, fd2, retval; char *buf; struct stat info; kern_return_t ret; fd1 = open(file, O_RDONLY, 0666); if (fd1 < 0) { perror("open"); return -1; } if (fstat(fd1, &info) < 0) { perror("fstat"); return -1; } if (info.st_size < 0 || (info.st_mode & S_IFMT) != S_IFREG) { return -1; } if ((ret = map_fd(fd1, 0, (vm_offset_t *)&buf, TRUE, info.st_size)) != KERN_SUCCESS) { mach_error("map_fd", ret); return -1; } fd2 = open(copy, O_WRONLY | O_CREAT, 0666); if (fd2 < 0) { perror("open"); return -1; } retval = write(fd2, buf, info.st_size); if (retval < 0) { perror("write"); return retval; } retval = fsync(fd2); if (retval < 0) { perror("fsync"); return retval; } retval = close(fd2); if (retval < 0) { perror("close"); return retval; } retval = close(fd1); if (retval < 0) { perror("close"); return retval; } ret = vm_deallocate(mach_task_self(), (vm_offset_t)buf, (vm_size_t)info.st_size); if (ret != KERN_SUCCESS) { mach_error("vm_deallocate", ret); return ret; } return 0; }
static void dotest(int testers, int me, int fd) { char *bits, *hold_bits; char val; int count, collide, chunk, whenmisc, xfr, i; /* Stuff for the readv call */ struct iovec r_iovec[MAXIOVCNT]; int r_ioveclen; /* Stuff for the writev call */ struct iovec val_iovec[MAXIOVCNT]; struct iovec zero_iovec[MAXIOVCNT]; int w_ioveclen; nchunks = max_size / csize; if ((bits = malloc((nchunks+7) / 8)) == NULL) { tst_resm(TBROK, "\tmalloc failed(bits)"); tst_exit(); } if ((hold_bits = malloc((nchunks+7) / 8)) == NULL) { tst_resm(TBROK, "\tmalloc failed(hlod_bits)"); tst_exit(); } /*Allocate memory for the iovec buffers and init the iovec arrays */ r_ioveclen = w_ioveclen = csize / MAXIOVCNT; /* Please note that the above statement implies that csize * be evenly divisible by MAXIOVCNT. */ for (i = 0; i < MAXIOVCNT; i++) { if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == NULL) { tst_resm(TFAIL, "\tmalloc failed(r_iovec[i].iov_base)"); tst_exit(); } r_iovec[i].iov_len = r_ioveclen; /* Allocate unused memory areas between all the buffers to * make things more diffult for the OS. */ if (malloc((i+1)*8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) { tst_resm(TBROK, "\tmalloc failed(val_iovec[i]"); exit(1); } val_iovec[i].iov_len = w_ioveclen; if (malloc((i+1)*8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) { tst_resm(TBROK, "\tmalloc failed(zero_iover)"); tst_exit(); } zero_iovec[i].iov_len = w_ioveclen; if (malloc((i+1)*8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } } /* * No init sectors; allow file to be sparse. */ val = (64/testers) * me + 1; /* * For each iteration: * zap bits array * loop * pick random chunk, read it. * if corresponding bit off { * verify = 0. (sparse file) * ++count; * } else * verify = val. * write "val" on it. * repeat unitl count = nchunks. * ++val. */ srand(getpid()); if (misc_intvl) whenmisc = NEXTMISC; while (iterations-- > 0) { for (i = 0; i < NMISC; i++) misc_cnt[i] = 0; ftruncate(fd,0); file_max = 0; memset(bits, 0, (nchunks+7) / 8); memset(hold_bits, 0, (nchunks+7) / 8); /* Have to fill the val and zero iov buffers in a different manner */ for (i = 0; i < MAXIOVCNT; i++) { memset(val_iovec[i].iov_base,val,val_iovec[i].iov_len); memset(zero_iovec[i].iov_base,0,zero_iovec[i].iov_len); } count = 0; collide = 0; while (count < nchunks) { chunk = rand() % nchunks; /* * Read it. */ if (lseek64(fd, CHUNK(chunk), 0) < 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64(0) fail at %Lx, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) { tst_resm(TFAIL, "\tTest[%d]: readv fail at %Lx, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } /* * If chunk beyond EOF just write on it. * Else if bit off, haven't seen it yet. * Else, have. Verify values. */ if (CHUNK(chunk) >= file_max) { bits[chunk/8] |= (1<<(chunk%8)); ++count; } else if ((bits[chunk/8] & (1<<(chunk%8))) == 0) { if (xfr != csize) { tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, zero read.", me, xfr, csize); tst_exit(); } for (i = 0; i < MAXIOVCNT; i++) { if (memcmp(r_iovec[i].iov_base, zero_iovec[i].iov_base, r_iovec[i].iov_len)) { tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x, should be 0.", me, CHUNK(chunk), val, count, xfr, file_max); tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.", me, last_trunc); sync(); ft_dumpiov(&r_iovec[i]); ft_dumpbits(bits, (nchunks+7)/8); ft_orbits(hold_bits, bits, (nchunks+7)/8); tst_resm(TINFO, "\tHold "); ft_dumpbits(hold_bits, (nchunks+7)/8); tst_exit(); } } bits[chunk/8] |= (1<<(chunk%8)); ++count; } else { if (xfr != csize) { tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, val read.", me, xfr, csize); tst_exit(); } ++collide; for (i = 0; i < MAXIOVCNT; i++) { if (memcmp(r_iovec[i].iov_base, val_iovec[i].iov_base, r_iovec[i].iov_len)) { tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x.", me, CHUNK(chunk), val, count, xfr, file_max); tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.", me, last_trunc); sync(); ft_dumpiov(&r_iovec[i]); ft_dumpbits(bits, (nchunks+7)/8); ft_orbits(hold_bits, bits, (nchunks+7)/8); tst_resm(TINFO, "\tHold "); ft_dumpbits(hold_bits, (nchunks+7)/8); tst_exit(); } } } /* * Writev it. */ if (lseek64(fd, -((off64_t)xfr), 1) < 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64(1) fail at %Lx, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } if ((xfr = writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) { if (errno == ENOSPC) { tst_resm(TFAIL, "\tTest[%d]: no space, exiting.", me); fsync(fd); tst_exit(); } tst_resm(TFAIL, "\tTest[%d]: writev fail at %Lx xfr %d, errno = %d.", me, CHUNK(chunk), xfr, errno); tst_exit(); } if (CHUNK(chunk) + csize > file_max) file_max = CHUNK(chunk) + csize; /* * If hit "misc" interval, do it. */ if (misc_intvl && --whenmisc <= 0) { ft_orbits(hold_bits, bits, (nchunks+7)/8); domisc(me, fd, bits); whenmisc = NEXTMISC; } if (count + collide > 2 * nchunks) break; } /* * End of iteration, maybe before doing all chunks. */ fsync(fd); ++misc_cnt[m_fsync]; //tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}", // me, val, count, collide); //for(i = 0; i < NMISC; i++) // tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]); ++val; } }
void x_vpx_enc_run(unsigned char *pixels, int w, int h, int sock, struct sockaddr_in *cli) { size_t len = 0; int p1x = 0; int p1y = 0; void *dat; vpx_codec_ctx_t _encoder; vpx_codec_ctx_t _decoder; vpx_image_t raw_yuv; const vpx_codec_cx_pkt_t *pkt; int frame_cnt = 0; int flags = 0; vpx_codec_iter_t iter; int outfd; int infd; int mem_fdmap; memset(&_encoder, 0, sizeof(_encoder)); x_vpx_encoder_init(&_encoder, 1, w, h); memset(&_decoder, 0, sizeof(_decoder)); x_vpx_decoder_init(&_decoder, 1); vpx_img_alloc(&raw_yuv, VPX_IMG_FMT_YV12, w, h, 0); memset(raw_yuv.planes[VPX_PLANE_Y], 0, raw_yuv.stride[VPX_PLANE_Y] * raw_yuv.d_h / 2); // outfd = _P(open)("x_vp8_out.yuv",_P(O_CREAT) | _P(O_RDWR)); infd = _P(open)("x_camera_in.yuv", _P(O_RDONLY)); for (;;) { #if 0 raw_yuv.planes[VPX_PLANE_Y][p1y * w + p1x] = 0x0; p1x++; if (p1x > w) { p1x = 0; p1y++; if (p1y > h) p1y = 0; } raw_yuv.planes[VPX_PLANE_Y][p1y * w + p1x] = 0xff; #endif // int rbytes; // int bufsiz = ycbcr[0].width*ycbcr[0].height // + ycbcr[1].width*ycbcr[1].height + ycbcr[2].width*ycbcr[2].height; /* read luminance */ x_read(infd, raw_yuv.planes[VPX_PLANE_Y], raw_yuv.w * raw_yuv.h); /* read chroma U */ x_read(infd, raw_yuv.planes[VPX_PLANE_U], (raw_yuv.w * raw_yuv.h) >> 2); /* read chroma V */ x_read(infd, raw_yuv.planes[VPX_PLANE_V], (raw_yuv.w * raw_yuv.h) >> 2); // x_vp8_write_frame(outfd,&raw_yuv); if (vpx_codec_encode(&_encoder, &raw_yuv, frame_cnt, 1, flags, VPX_DL_REALTIME )) { die_codec(&_encoder, "vpx_codec_enc_init()"); } iter = NULL; while ((pkt = vpx_codec_get_cx_data(&_encoder, &iter))) { switch (pkt->kind) { case VPX_CODEC_CX_FRAME_PKT: // __decode_vp8_pkt(&_decoder, pkt->data.frame.buf, pkt->data.frame.sz, outfd); x_vp8_rtp_send((int) sock, (void *) pkt->data.frame.buf, (int) pkt->data.frame.sz, (struct sockaddr *) cli, (int) sizeof(*cli), seqno * 90); break; default: break; } x_write(1, (pkt->kind == VPX_CODEC_CX_FRAME_PKT) && (pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? "K" : (pkt->kind == VPX_CODEC_CX_FRAME_PKT) && (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) ? "I" : (pkt->kind == VPX_CODEC_CX_FRAME_PKT) && (pkt->data.frame.flags & VPX_FRAME_IS_DROPPABLE) ? "D" : (pkt->kind == VPX_CODEC_CX_FRAME_PKT) && (pkt->data.frame.flags & 0x3) ? "B" : ".", 1); #ifndef WIN32 fsync(1); #endif } frame_cnt++; #ifdef WIN32 Sleep(20); #else usleep(56000); #endif } }
void GenerateJson() { char tmp[256]; static char* buff = NULL; miniemc::EmcController* pCtrl = miniemc::EmcController::Instance(); if( pCtrl->GetInitState() == miniemc::EmcController::lsLoaded ) { if( !buff ) buff = (char*) malloc(32768); strcpy(buff, "{\n \"positions\":["); /* * Append Positions */ for(int i = 0; i < pCtrl->GetAxisNumber(); i++) { char name = pCtrl->GetAxisName( i ); sprintf(buff+strlen(buff), "%.4f", pCtrl->GetAxisPosition(name) ); if( i != pCtrl->GetAxisNumber() -1 ) strcat(buff, ","); } /* * Append feedrate */ strcat(buff, "],\n\"feed\":"); sprintf( buff+ strlen(buff), "%.2f,\n", pCtrl->GetVelocity() ); /* * Append Relative/Absolute position type */ sprintf( buff+ strlen(buff), "\"pos_abs\":%s,\n", pCtrl->IsPositionAbsolute() ? "true" : "false" ); /* * Append Limits overrided or not flag */ sprintf( buff+ strlen(buff), "\"limit_over\":%s,\n", pCtrl->IsLimitsOverrided() ? "true" : "false" ); // Active modal G-code memset(tmp, 0 , sizeof(tmp) ); pCtrl->GetActiveCodes(tmp); sprintf( buff+ strlen(buff), "\"active_codes\": \"%s\",\n", tmp ); //Current offsets //miniemc::Coord coord = pCtrl->GetCurrentOffset(); miniemc::Coord coord = pCtrl->GetCurrentOrigin(); sprintf( buff+ strlen(buff), "\"offsets\":[%.3f,%.3f,%.3f,%.3f,%.3f,%.3f],\n", coord.GetPosIndex(0), coord.GetPosIndex(1), coord.GetPosIndex(2), coord.GetPosIndex(3), coord.GetPosIndex(4), coord.GetPosIndex(5) ); //Controller state, see enum miniemc::EmcController::ecState sprintf( buff+ strlen(buff), "\"ctrl_state\":%d,\n", pCtrl->GetControllerState() ); // Controller mode , see miniemc::EmcController::eCtlMode sprintf( buff+ strlen(buff), "\"ctrl_mode\":%d,\n", pCtrl->GetControllerMode() ); // Interpretter state sprintf( buff+ strlen(buff), "\"interp_state\":%d,\n", pCtrl->GetInterpState() ); // Is machine in position ? sprintf( buff+ strlen(buff), "\"inpos\":%s,\n", pCtrl->IsInpos() ? "true" : "false" ); // Is spindle on ? sprintf( buff+ strlen(buff), "\"spindle_on\":%s,\n", pCtrl->IsSpindleOn() ? "true" : "false" ); // Get infos if(pCtrl->GetErrorCount(miniemc::EmcController::elInfo) > 0 ) { strcat(buff, "\"info\": ["); while(pCtrl->GetErrorCount(miniemc::EmcController::elInfo)) { sprintf( buff+ strlen(buff), "\"%s\"", pCtrl->GetNextError(miniemc::EmcController::elInfo).c_str() ); if(pCtrl->GetErrorCount(miniemc::EmcController::elInfo) ) { strcat(buff, ","); } } strcat(buff, "],\n"); } // Get warnings if(pCtrl->GetErrorCount(miniemc::EmcController::elWarning) > 0 ) { strcat(buff, "\"warn\": ["); while(pCtrl->GetErrorCount(miniemc::EmcController::elWarning)) { sprintf( buff+ strlen(buff), "\"%s\"", pCtrl->GetNextError(miniemc::EmcController::elWarning).c_str() ); if(pCtrl->GetErrorCount(miniemc::EmcController::elWarning) ) { strcat(buff, ","); } } strcat(buff, "],\n"); } // Get errorss if(pCtrl->GetErrorCount(miniemc::EmcController::elError) > 0 ) { strcat(buff, "\"errors\": ["); while(pCtrl->GetErrorCount(miniemc::EmcController::elError)) { sprintf( buff+ strlen(buff), "\"%s\"", pCtrl->GetNextError(miniemc::EmcController::elError).c_str() ); if(pCtrl->GetErrorCount(miniemc::EmcController::elError) ) { strcat(buff, ","); } } strcat(buff, "],\n"); } sprintf( buff+ strlen(buff), "\"last_program\":\"%s\",\n", pCtrl->GetLastFileName() ); // Get num lines per context sprintf( buff+ strlen(buff), "\"context_size\":%d,\n", pCtrl->GetNumLinesPerContext() ); // Get current context index sprintf( buff+ strlen(buff), "\"context_index\":%d,\n", pCtrl->GetActualContextIndex() ); // Offset with actual context sprintf( buff+ strlen(buff), "\"context_offset\":%d,\n", pCtrl->GetCurrPosInContext() ); // Context changed flag sprintf( buff+ strlen(buff), "\"context_changed\":%s\n", pCtrl->isContextChanged() ? "true" : "false" ); strcat(buff, "}"); /* * Write to disk */ int fd = open("/tmp/emc_dynamic.json", O_WRONLY | O_TRUNC | O_SYNC | O_CREAT); if( fd >= 0) { write(fd, buff, strlen(buff)); fsync(fd); close(fd); } else { fprintf(stderr, "can't open /tmp/emc_dynamic.json for write!"); } } }
int fdatasync(int filedes) { return fsync(filedes); }
/************************************************************************** * private functions **************************************************************************/ static int _commitLocalBuffer(const char *iRODSPath, struct fuse_file_info *fi, lazyUploadFileInfo_t *lazyUploadFileInfo) { int status; int desc; char bufferPath[MAX_NAME_LEN]; int descInx; status = _getBufferPath(iRODSPath, bufferPath); if(status < 0) { rodsLog (LOG_DEBUG, "_upload: failed to get Buffered lazy upload file path - %s", iRODSPath); return status; } // close local buffer file handle if(lazyUploadFileInfo->localHandle < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: wrong file descriptor - %s, %d", iRODSPath, lazyUploadFileInfo->localHandle); return -EBADF; } // no write but requested flush if(lazyUploadFileInfo->curOffset == 0) { return 0; } fsync(lazyUploadFileInfo->localHandle); close(lazyUploadFileInfo->localHandle); lazyUploadFileInfo->localHandle = -1; rodsLog (LOG_DEBUG, "_commitLocalBuffer: upload - %s", iRODSPath); if(lazyUploadFileInfo->commitCount == 0) { // put and reopen iRODS file dataObjInp_t dataObjInp; int fd; pathCache_t *tmpPathCache = NULL; iFuseConn_t *iFuseConn = NULL; iFuseDesc_t *desc = NULL; struct stat stbuf; char objPath[MAX_NAME_LEN]; descInx = GET_IFUSE_DESC_INDEX(fi); rodsLog (LOG_DEBUG, "_commitLocalBuffer: closing existing iRODS file handle - %s - %d", iRODSPath, descInx); status = ifuseClose (&IFuseDesc[descInx]); if (status < 0) { int myError; if ((myError = getErrno (status)) > 0) { return (-myError); } else { return -ENOENT; } } // put rodsLog (LOG_DEBUG, "_commitLocalBuffer: uploading buffered file - %s", iRODSPath); status = _upload(iRODSPath); if(status != 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: upload error - %s, %d", iRODSPath, status); return status; } // reopen file rodsLog (LOG_DEBUG, "_commitLocalBuffer: reopening iRODS file handle - %s", iRODSPath); memset (&dataObjInp, 0, sizeof (dataObjInp)); //dataObjInp.openFlags = lazyUploadFileInfo->accmode; dataObjInp.openFlags = O_RDWR | O_APPEND; status = parseRodsPathStr ((char *) iRODSPath, LazyUploadRodsEnv, objPath); rstrcpy(dataObjInp.objPath, objPath, MAX_NAME_LEN); if (status < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: parseRodsPathStr of %s error", iRODSPath); /* use ENOTDIR for this type of error */ return -ENOTDIR; } iFuseConn = getAndUseConnByPath((char *) iRODSPath, &status); /* status = getAndUseIFuseConn(&iFuseConn); */ if(status < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: cannot get connection for %s error", iRODSPath); /* use ENOTDIR for this type of error */ return -ENOTDIR; } status = _irodsGetattr (iFuseConn, iRODSPath, &stbuf); fd = rcDataObjOpen (iFuseConn->conn, &dataObjInp); unuseIFuseConn (iFuseConn); if (fd < 0) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: rcDataObjOpen of %s error, status = %d", iRODSPath, fd); return -ENOENT; } fileCache_t *fileCache = addFileCache(fd, objPath, (char *) iRODSPath, NULL, stbuf.st_mode, stbuf.st_size, NO_FILE_CACHE); matchAndLockPathCache(pctable, (char *) iRODSPath, &tmpPathCache); if(tmpPathCache == NULL) { pathExist(pctable, (char *) iRODSPath, fileCache, &stbuf, NULL); } else { _addFileCacheForPath(tmpPathCache, fileCache); UNLOCK_STRUCT(*tmpPathCache); } desc = newIFuseDesc (objPath, (char *) iRODSPath, fileCache, &status); if (desc == NULL) { rodsLogError (LOG_ERROR, status, "_commitLocalBuffer: allocIFuseDesc of %s error", iRODSPath); return -ENOENT; } SET_IFUSE_DESC_INDEX(fi, desc->index); rodsLog (LOG_DEBUG, "_commitLocalBuffer: created new file handle - %s - %d", iRODSPath, desc->index); } else { // append int localDesc = open (bufferPath, O_RDONLY, 0755); char *buffer = (char*)malloc(FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE); int grandTotalReadLen = 0; if(localDesc < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: file descriptor error - %s, %d", iRODSPath, localDesc); return -ENOENT; } descInx = GET_IFUSE_DESC_INDEX(fi); if (checkFuseDesc (descInx) < 0) { return -EBADF; } status = 0; while(grandTotalReadLen < lazyUploadFileInfo->curOffset) { int totalReadLen = 0; int totalWriteLen = 0; while(totalReadLen < FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE) { int readLen = read(localDesc, buffer + totalReadLen, FUSE_LAZY_UPLOAD_MEM_BUFFER_SIZE - totalReadLen); if(readLen > 0) { totalReadLen += readLen; } else if(readLen == 0) { // EOF break; } else if(readLen < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: buffered file read error - %s, %d", iRODSPath, localDesc); status = getErrno (readLen); break; } } if(status >= 0) { while(totalWriteLen < totalReadLen) { int writeLen = _ifuseWrite (&IFuseDesc[descInx], buffer + totalWriteLen, totalReadLen - totalWriteLen, lazyUploadFileInfo->curLocalOffsetStart + totalWriteLen); if(writeLen > 0) { totalWriteLen += writeLen; } else if(writeLen == 0) { // EOF break; } else if(writeLen < 0) { rodsLog (LOG_DEBUG, "_commitLocalBuffer: iRODS file write error - %s", iRODSPath); status = getErrno (writeLen); break; } } } grandTotalReadLen += totalReadLen; } unlockDesc (descInx); free(buffer); close(localDesc); } rodsLog (LOG_DEBUG, "_commitLocalBuffer: reset local buffered file - %s", iRODSPath); // reset local buffer file desc = open (bufferPath, O_RDWR|O_CREAT|O_TRUNC, 0755); lazyUploadFileInfo->localHandle = desc; lazyUploadFileInfo->commitCount++; lazyUploadFileInfo->curLocalOffsetStart += lazyUploadFileInfo->curOffset; lazyUploadFileInfo->curOffset = 0; return (0); }
static int handle_decrypt(int stdout_fd, const char *password) { DIR *d; struct dirent *de; char buff[256]; int res = -1; static const char *default_password = "******"; if(cryptfs_check_footer() < 0) { ERROR("cryptfs_check_footer failed!"); return -1; } int pwtype = cryptfs_get_password_type(); if(pwtype < 0) { ERROR("cryptfs_get_password_type failed!"); return -1; } else if (pwtype == CRYPT_TYPE_DEFAULT) password = default_password; if(password) { if(cryptfs_check_passwd(password) < 0) { ERROR("cryptfs_check_passwd failed!"); return -1; } } else { switch(pw_ui_run(pwtype)) { default: case ENCMNT_UIRES_ERROR: ERROR("pw_ui_run() failed!\n"); return -1; case ENCMNT_UIRES_BOOT_INTERNAL: INFO("Wants to boot internal!\n"); write(stdout_fd, ENCMNT_BOOT_INTERNAL_OUTPUT, strlen(ENCMNT_BOOT_INTERNAL_OUTPUT)); fsync(stdout_fd); return 0; case ENCMNT_UIRES_BOOT_RECOVERY: INFO("Wants to boot recoveryl!\n"); write(stdout_fd, ENCMNT_BOOT_RECOVERY_OUTPUT, strlen(ENCMNT_BOOT_RECOVERY_OUTPUT)); fsync(stdout_fd); return 0; case ENCMNT_UIRES_PASS_OK: break; } } d = opendir("/dev/block/"); if(!d) { ERROR("Failed to open /dev/block, wth? %s", strerror(errno)); return -1; } // find the block device while((de = readdir(d))) { if(de->d_type == DT_BLK && strncmp(de->d_name, "dm-", 3) == 0) { snprintf(buff, sizeof(buff), "/dev/block/%s\n", de->d_name); INFO("Found block device %s\n", buff); write(stdout_fd, buff, strlen(buff)); fsync(stdout_fd); res = 0; break; } } closedir(d); return res; }
static void file_flush( struct fd *fd, struct event **event ) { int unix_fd = get_unix_fd( fd ); if (unix_fd != -1 && fsync( unix_fd ) == -1) file_set_error(); }
static int GenerateTarget(FileContents* source_file, const Value* source_patch_value, FileContents* copy_file, const Value* copy_patch_value, const char* source_filename, const char* target_filename, const uint8_t target_sha1[SHA_DIGEST_SIZE], size_t target_size, const Value* bonus_data) { int retry = 1; SHA_CTX ctx; int output; MemorySinkInfo msi; FileContents* source_to_use; char* outname; int made_copy = 0; // assume that target_filename (eg "/system/app/Foo.apk") is located // on the same filesystem as its top-level directory ("/system"). // We need something that exists for calling statfs(). char target_fs[strlen(target_filename)+1]; char* slash = strchr(target_filename+1, '/'); if (slash != NULL) { int count = slash - target_filename; strncpy(target_fs, target_filename, count); target_fs[count] = '\0'; } else { strcpy(target_fs, target_filename); } do { // Is there enough room in the target filesystem to hold the patched // file? if (strncmp(target_filename, "MTD:", 4) == 0 || strncmp(target_filename, "EMMC:", 5) == 0) { // If the target is a partition, we're actually going to // write the output to /tmp and then copy it to the // partition. statfs() always returns 0 blocks free for // /tmp, so instead we'll just assume that /tmp has enough // space to hold the file. // We still write the original source to cache, in case // the partition write is interrupted. if (source_patch_value != NULL) { //wschen 2013-05-24 must check the source is complete if (MakeFreeSpaceOnCache(source_file->size) < 0) { printf("not enough free space on /cache\n"); return 1; } if (SaveFileContents(CACHE_TEMP_SOURCE, source_file) < 0) { printf("failed to back up source file\n"); return 1; } } made_copy = 1; retry = 0; } else { int enough_space = 0; if (retry > 0) { size_t free_space = FreeSpaceForFile(target_fs); enough_space = (free_space > (256 << 10)) && // 256k (two-block) minimum (free_space > (target_size * 3 / 2)); // 50% margin of error if (!enough_space) { printf("target %ld bytes; free space %ld bytes; retry %d; enough %d\n", (long)target_size, (long)free_space, retry, enough_space); } } if (!enough_space) { retry = 0; } if (!enough_space && source_patch_value != NULL) { // Using the original source, but not enough free space. First // copy the source file to cache, then delete it from the original // location. if (strncmp(source_filename, "MTD:", 4) == 0 || strncmp(source_filename, "EMMC:", 5) == 0) { // It's impossible to free space on the target filesystem by // deleting the source if the source is a partition. If // we're ever in a state where we need to do this, fail. printf("not enough free space for target but source " "is partition\n"); return 1; } if (MakeFreeSpaceOnCache(source_file->size) < 0) { printf("not enough free space on /cache\n"); return 1; } if (SaveFileContents(CACHE_TEMP_SOURCE, source_file) < 0) { printf("failed to back up source file\n"); return 1; } made_copy = 1; unlink(source_filename); size_t free_space = FreeSpaceForFile(target_fs); printf("(now %ld bytes free for target) ", (long)free_space); } #if 1 //wschen 2013-05-24 still backup file to cache if (enough_space && (source_patch_value != NULL)) { if (strncmp(source_filename, "MTD:", 4) && strncmp(source_filename, "EMMC:", 5)) { if (MakeFreeSpaceOnCache(source_file->size) == 0) { if (SaveFileContents(CACHE_TEMP_SOURCE, source_file) == 0) { made_copy = 1; } } } } #endif } const Value* patch; if (source_patch_value != NULL) { source_to_use = source_file; patch = source_patch_value; } else { source_to_use = copy_file; patch = copy_patch_value; } if (patch->type != VAL_BLOB) { printf("patch is not a blob\n"); return 1; } #if 1 //wschen 2013-05-23 if (patch->data == NULL) { printf("patch data is invalid\n"); return 1; } #endif SinkFn sink = NULL; void* token = NULL; output = -1; outname = NULL; if (strncmp(target_filename, "MTD:", 4) == 0 || strncmp(target_filename, "EMMC:", 5) == 0) { // We store the decoded output in memory. msi.buffer = malloc(target_size); if (msi.buffer == NULL) { printf("failed to alloc %ld bytes for output\n", (long)target_size); return 1; } msi.pos = 0; msi.size = target_size; sink = MemorySink; token = &msi; } else { // We write the decoded output to "<tgt-file>.patch". outname = (char*)malloc(strlen(target_filename) + 10); strcpy(outname, target_filename); strcat(outname, ".patch"); output = open(outname, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR); if (output < 0) { printf("failed to open output file %s: %s\n", outname, strerror(errno)); return 1; } sink = FileSink; token = &output; } char* header = patch->data; ssize_t header_bytes_read = patch->size; SHA_init(&ctx); int result; if (header_bytes_read >= 8 && memcmp(header, "BSDIFF40", 8) == 0) { result = ApplyBSDiffPatch(source_to_use->data, source_to_use->size, patch, 0, sink, token, &ctx); } else if (header_bytes_read >= 8 && memcmp(header, "IMGDIFF2", 8) == 0) { result = ApplyImagePatch(source_to_use->data, source_to_use->size, patch, sink, token, &ctx, bonus_data); } else { printf("Unknown patch file format\n"); return 1; } if (output >= 0) { if (fsync(output) != 0) { printf("failed to fsync file \"%s\" (%s)\n", outname, strerror(errno)); result = 1; } if (close(output) != 0) { printf("failed to close file \"%s\" (%s)\n", outname, strerror(errno)); result = 1; } } if (result != 0) { if (retry == 0) { printf("applying patch failed\n"); return result != 0; } else { printf("applying patch failed; retrying\n"); } if (outname != NULL) { unlink(outname); } } else { // succeeded; no need to retry break; } } while (retry-- > 0); const uint8_t* current_target_sha1 = SHA_final(&ctx); if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) { printf("patch did not produce expected sha1\n"); return 1; } else { printf("now "); print_short_sha1(target_sha1); putchar('\n'); } if (output < 0) { // Copy the temp file to the partition. if (WriteToPartition(msi.buffer, msi.pos, target_filename) != 0) { printf("write of patched data to %s failed\n", target_filename); return 1; } free(msi.buffer); } else { // Give the .patch file the same owner, group, and mode of the // original source file. if (chmod(outname, source_to_use->st.st_mode) != 0) { printf("chmod of \"%s\" failed: %s\n", outname, strerror(errno)); return 1; } if (chown(outname, source_to_use->st.st_uid, source_to_use->st.st_gid) != 0) { printf("chown of \"%s\" failed: %s\n", outname, strerror(errno)); return 1; } // Finally, rename the .patch file to replace the target file. if (rename(outname, target_filename) != 0) { printf("rename of .patch to \"%s\" failed: %s\n", target_filename, strerror(errno)); return 1; } } // If this run of applypatch created the copy, and we're here, we // can delete it. if (made_copy) unlink(CACHE_TEMP_SOURCE); #if 1 //wschen 2013-05-23 sync(); #endif // Success! return 0; }
static void test_corruption(const char *filename, uint32_t write_chunk, uint32_t write_size, uint16_t flags) { printf("Testing on %s with write_chunk=%u write_size=%u\n", filename, (unsigned)write_chunk, (unsigned)write_size); uint32_t ofs = 0; int fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, PX4_O_MODE_666); if (fd == -1) { perror(filename); exit(1); } // create a file of size write_size, in write_chunk blocks uint8_t counter = 0; while (ofs < write_size) { uint8_t buffer[write_chunk]; for (uint16_t j = 0; j < write_chunk; j++) { buffer[j] = get_value(ofs); ofs++; } if (write(fd, buffer, sizeof(buffer)) != (int)sizeof(buffer)) { printf("write failed at offset %u\n", ofs); exit(1); } if (flags & FLAG_FSYNC) { fsync(fd); } if (counter % 100 == 0) { printf("write ofs=%u\r", ofs); } counter++; } close(fd); printf("write ofs=%u\n", ofs); // read and check fd = open(filename, O_RDONLY); if (fd == -1) { perror(filename); exit(1); } counter = 0; ofs = 0; while (ofs < write_size) { uint8_t buffer[write_chunk]; if (counter % 100 == 0) { printf("read ofs=%u\r", ofs); } counter++; if (read(fd, buffer, sizeof(buffer)) != (int)sizeof(buffer)) { printf("read failed at offset %u\n", ofs); close(fd); return; } for (uint16_t j = 0; j < write_chunk; j++) { if (buffer[j] != get_value(ofs)) { printf("corruption at ofs=%u got %u\n", ofs, buffer[j]); close(fd); return; } ofs++; } if (flags & FLAG_LSEEK) { lseek(fd, 0, SEEK_CUR); } } printf("read ofs=%u\n", ofs); close(fd); unlink(filename); printf("All OK\n"); }
int main(int argc, char* argv[], char *envp[] ) { cout << "hello" << endl; FILE *f = fopen("/data/db/temptest", "a"); if ( f == 0 ) { cout << "can't open file\n"; return 1; } { Timer t; for ( int i = 0; i < 50000; i++ ) fwrite("abc", 3, 1, f); cout << "small writes: " << t.millis() << "ms" << endl; } { Timer t; for ( int i = 0; i < 10000; i++ ) { fwrite("abc", 3, 1, f); fflush(f); fsync( fileno( f ) ); } int ms = t.millis(); cout << "flush: " << ms << "ms, " << ms / 10000.0 << "ms/request" << endl; } { Timer t; for ( int i = 0; i < 500; i++ ) { fwrite("abc", 3, 1, f); fflush(f); fsync( fileno( f ) ); sleepmillis(2); } int ms = t.millis() - 500 * 2; cout << "flush with sleeps: " << ms << "ms, " << ms / 500.0 << "ms/request" << endl; } char buf[8192]; for ( int pass = 0; pass < 2; pass++ ) { cout << "pass " << pass << endl; { Timer t; int n = 500; for ( int i = 0; i < n; i++ ) { if ( pass == 0 ) fwrite("abc", 3, 1, f); else fwrite(buf, 8192, 1, f); buf[0]++; fflush(f); fullsync(fileno(f)); } int ms = t.millis(); cout << "fullsync: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; } { Timer t; for ( int i = 0; i < 500; i++ ) { if ( pass == 0 ) fwrite("abc", 3, 1, f); else fwrite(buf, 8192, 1, f); buf[0]++; fflush(f); fullsync(fileno(f)); sleepmillis(2); } int ms = t.millis() - 2 * 500; cout << "fullsync with sleeps: " << ms << "ms, " << ms / 500.0 << "ms/request" << endl; } } // without growing { fclose(f); /* try from beginning of the file, where we aren't appending and changing the file length, to see if this is faster as the directory entry then doesn't have to be flushed (if noatime in effect). */ f = fopen("/data/db/temptest", "r+"); Timer t; int n = 500; for ( int i = 0; i < n; i++ ) { fwrite("xyz", 3, 1, f); fflush(f); fullsync(fileno(f)); } int ms = t.millis(); cout << "fullsync without growing: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; } // without growing, with delay { fclose(f); /* try from beginning of the file, where we aren't appending and changing the file length, to see if this is faster as the directory entry then doesn't have to be flushed (if noatime in effect). */ f = fopen("/data/db/temptest", "r+"); Timer t; int n = 500; for ( int i = 0; i < n; i++ ) { fwrite("xyz", 3, 1, f); fflush(f); fullsync(fileno(f)); sleepmillis(2); } int ms = t.millis() - 2 * 500; cout << "fullsync without growing with sleeps: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; } return 0; }
static int trunk_binlog_merge_file(int old_fd) { int result; int tmp_fd; int bytes; char binlog_filename[MAX_PATH_SIZE]; char tmp_filename[MAX_PATH_SIZE]; char buff[64 * 1024]; get_trunk_binlog_filename(binlog_filename); sprintf(tmp_filename, "%s.tmp", binlog_filename); tmp_fd = open(tmp_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (tmp_fd < 0) { result = errno != 0 ? errno : EACCES; logError("file: "__FILE__", line: %d, " \ "open file \"%s\" fail, " \ "errno: %d, error info: %s", \ __LINE__, tmp_filename, result, STRERROR(result)); return result; } while ((bytes=fc_safe_read(old_fd, buff, sizeof(buff))) > 0) { if (fc_safe_write(tmp_fd, buff, bytes) != bytes) { result = errno != 0 ? errno : EACCES; logError("file: "__FILE__", line: %d, " \ "write to file \"%s\" fail, " \ "errno: %d, error info: %s", \ __LINE__, tmp_filename, result, STRERROR(result)); close(tmp_fd); return result; } } if (access(binlog_filename, F_OK) == 0) { int binlog_fd; if ((binlog_fd=trunk_binlog_open_read(binlog_filename, false)) < 0) { close(tmp_fd); return errno != 0 ? errno : EPERM; } while ((bytes=fc_safe_read(binlog_fd, buff, sizeof(buff))) > 0) { if (fc_safe_write(tmp_fd, buff, bytes) != bytes) { result = errno != 0 ? errno : EACCES; logError("file: "__FILE__", line: %d, " \ "write to file \"%s\" fail, " \ "errno: %d, error info: %s", \ __LINE__, tmp_filename, result, STRERROR(result)); close(tmp_fd); close(binlog_fd); return result; } } close(binlog_fd); } if (fsync(tmp_fd) != 0) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "sync file \"%s\" fail, " \ "errno: %d, error info: %s", \ __LINE__, tmp_filename, \ errno, STRERROR(errno)); close(tmp_fd); return result; } close(tmp_fd); if (rename(tmp_filename, binlog_filename) != 0) { result = errno != 0 ? errno : EPERM; logError("file: "__FILE__", line: %d, " \ "rename %s to %s fail, " \ "errno: %d, error info: %s", __LINE__, tmp_filename, binlog_filename, result, STRERROR(result)); return result; } return 0; }
bool TextBuffer::save (const QString &filename) { // codec must be set! Q_ASSERT (m_textCodec); /** * construct correct filter device and try to open */ QIODevice *file = KFilterDev::deviceForFile (filename, m_mimeTypeForFilterDev, false); if (!file->open (QIODevice::WriteOnly)) { delete file; return false; } /** * construct stream + disable Unicode headers */ QTextStream stream (file); stream.setCodec (QTextCodec::codecForName("UTF-16")); // set the correct codec stream.setCodec (m_textCodec); // generate byte order mark? stream.setGenerateByteOrderMark (generateByteOrderMark()); // our loved eol string ;) QString eol = "\n"; //m_doc->config()->eolString (); if (endOfLineMode() == eolDos) eol = QString ("\r\n"); else if (endOfLineMode() == eolMac) eol = QString ("\r"); // just dump the lines out ;) for (int i = 0; i < m_lines; ++i) { // get line to save Kate::TextLine textline = line (i); // strip trailing spaces if (m_removeTrailingSpaces) { int lastChar = textline->lastChar(); if (lastChar > -1) { stream << textline->text().left (lastChar+1); } } else // simple, dump the line stream << textline->text(); // append correct end of line string if ((i+1) < m_lines) stream << eol; } // flush stream stream.flush (); // close and delete file file->close (); delete file; #ifndef Q_OS_WIN // ensure that the file is written to disk // we crete new qfile, as the above might be wrapper around compression QFile syncFile (filename); syncFile.open (QIODevice::ReadOnly); #ifdef HAVE_FDATASYNC fdatasync (syncFile.handle()); #else fsync (syncFile.handle()); #endif #endif // did save work? bool ok = stream.status() == QTextStream::Ok; // remember this revision as last saved if we had success! if (ok) m_history.setLastSavedRevision (); // report CODEC + ERRORS kDebug (13020) << "Saved file " << filename << "with codec" << m_textCodec->name() << (ok ? "without" : "with") << "errors"; if (ok) markModifiedLinesAsSaved(); // emit signal on success if (ok) emit saved (filename); // return success or not return ok; }
int commonio_close(struct commonio_db *db) { char buf[1024]; int errors = 0; struct stat sb; if (!db->isopen) { errno = EINVAL; return 0; } db->isopen = 0; if (!db->changed || db->readonly) { fclose(db->fp); db->fp = NULL; goto success; } memzero(&sb, sizeof sb); if (db->fp) { if (fstat(fileno(db->fp), &sb)) { fclose(db->fp); db->fp = NULL; goto fail; } /* * Create backup file. */ snprintf(buf, sizeof buf, "%s-", db->filename); if (create_backup(buf, db->fp)) errors++; if (fclose(db->fp)) errors++; if (errors) { db->fp = NULL; goto fail; } } else { /* * Default permissions for new [g]shadow files. * (passwd and group always exist...) */ sb.st_mode = 0400; sb.st_uid = 0; sb.st_gid = 0; } snprintf(buf, sizeof buf, "%s+", db->filename); db->fp = fopen_set_perms(buf, "w", &sb); if (!db->fp) goto fail; if (write_all(db)) errors++; if (fflush(db->fp)) errors++; #ifdef HAVE_FSYNC if (fsync(fileno(db->fp))) errors++; #else sync(); #endif if (fclose(db->fp)) errors++; db->fp = NULL; if (errors) { unlink(buf); goto fail; } if (rename(buf, db->filename)) goto fail; nscd_need_reload = 1; success: free_linked_list(db); return 1; fail: free_linked_list(db); return 0; }
/* Save mbox changes. */ int fetch_mbox_save(struct account *a, struct fetch_mbox_mbox *fmbox) { struct fetch_mbox_data *data = a->data; struct fetch_mbox_mail *aux, *this; char path[MAXPATHLEN], saved[MAXPATHLEN], c; int fd; ssize_t n; struct iovec iov[2]; log_debug2("%s: %s: saving mbox: %u kept, %u total", a->name, fmbox->path, fmbox->reference, fmbox->total); fd = -1; /* * If the reference count is 0, no mails were kept, so the mbox can * just be truncated. */ if (fmbox->reference == 0) { if (fmbox->total != 0 && ftruncate(fmbox->fd, 0) != 0) goto error; goto free_all; } /* If all the mails were kept, do nothing. */ if (fmbox->reference == fmbox->total) goto free_all; /* * Otherwise, things get complicated. data->kept is a list of all the * mails (struct fetch_mbox_mail) which were kept for ALL mailboxes. * There is no guarantee it is ordered by offset. Rather than try to be * clever and save disk space, just create a new mbox and copy all the * kept mails into it. */ if (ppath(path, sizeof path, "%s.XXXXXXXXXX", fmbox->path) != 0) goto error; if (ppath(saved, sizeof saved, "%s.XXXXXXXXXX", fmbox->path) != 0) goto error; if ((fd = mkstemp(path)) == -1) goto error; aux = TAILQ_FIRST(&data->kept); while (aux != NULL) { this = aux; aux = TAILQ_NEXT(aux, entry); if (this->fmbox != fmbox) continue; log_debug2("%s: writing message from %zu, size %zu", a->name, this->off, this->size); c = '\n'; iov[0].iov_base = fmbox->base + this->off; iov[0].iov_len = this->size; iov[1].iov_base = &c; iov[1].iov_len = 1; if ((n = writev(fd, iov, 2)) < 0) goto error; if ((size_t) n != this->size + 1) { errno = EIO; goto error; } fetch_mbox_free(this); TAILQ_REMOVE(&data->kept, this, entry); } if (fsync(fd) != 0) goto error; close(fd); /* * Do the replacement dance: create a backup copy of the mbox, remove * the mbox, link in the temporary file, unlink the temporary file, * then unlink the backup mbox. We don't try to recover if anything * fails on the grounds that it could just make things worse, just * die and let the user sort it out. */ if (link(fmbox->path, saved) != 0) goto error; if (unlink(fmbox->path) != 0) goto error; if (link(path, fmbox->path) != 0) goto error; if (unlink(path) != 0) goto error; if (unlink(saved) != 0) goto error; free_all: aux = TAILQ_FIRST(&data->kept); while (aux != NULL) { this = aux; aux = TAILQ_NEXT(aux, entry); if (this->fmbox == fmbox) fetch_mbox_free(this); } if (fmbox->reference != 0) fatalx("dangling reference"); return (0); error: if (fd != -1) { close(fd); unlink(path); } log_warn("%s: %s", a->name, fmbox->path); return (-1); }
int run_file_tests(char *testfile) { int ret = -1; struct stat buf; assert(testfile); fprintf(stdout, "Testing creat"); ret = creat(testfile, S_IRWXU); check_err(ret, "creat", 2); fprintf(stdout, "Testing close"); ret = close(ret); check_err(ret, "close", 2); fprintf(stdout, "Testing open"); ret = open(testfile, O_RDONLY); check_err(ret, "open", 2); fprintf(stdout, "Testing read"); ret = read(0, NULL, 0); check_err(ret, "read", 2); fprintf(stdout, "Testing readv"); ret = readv(0, NULL, 0); check_err(ret, "readv", 2); fprintf(stdout, "Testing pread"); ret = pread(0, NULL, 0, 0); check_err(ret, "pread", 2); fprintf(stdout, "Testing write"); ret = write(0, NULL, 0); check_err(ret, "write", 2); fprintf(stdout, "Testing writev"); ret = writev(0, NULL, 0); check_err(ret, "writev", 2); fprintf(stdout, "Testing pwrite"); ret = pwrite(0, NULL, 0, 0); check_err(ret, "pwrite", 2); fprintf(stdout, "Testing lseek"); ret = lseek(0, 0, 0); check_err(ret, "lseek", 2); fprintf(stdout, "Testing dup"); ret = dup(0); check_err(ret, "dup", 2); fprintf(stdout, "Testing dup2"); ret = dup2(0, 0); check_err(ret, "dup2", 2); fprintf(stdout, "Testing fchmod"); ret = fchmod(0, 0); check_err(ret, "fchmod", 2); fprintf(stdout, "Testing fchown"); ret = fchown(0, 0, 0); check_err(ret, "fchown", 2); fprintf(stdout, "Testing fsync"); ret = fsync(0); check_err(ret, "fsync", 2); fprintf(stdout, "Testing ftruncate"); ret = ftruncate(0, 0); check_err(ret, "ftruncate", 1); fprintf(stdout, "Testing fstat"); ret = fstat(0, &buf); check_err(ret, "fstat", 1); fprintf(stdout, "Testing sendfile"); ret = sendfile(0, 0, NULL, 0); check_err(ret, "sendfile", 1); fprintf(stdout, "Testing fcntl"); ret = fcntl(0, 0, NULL); check_err(ret, "fcntl", 2); fprintf(stdout, "Testing close"); ret = close(ret); check_err(ret, "close", 2); fprintf(stdout, "Testing remove"); ret = remove(testfile); check_err(ret, "remove", 2); return ret; }
axStatus axFile::flush () { int b = fsync( h_ ); if( b != 0 ) return axStatus_Std::File_error; return 0; }
gboolean crm_add_logfile(const char *filename) { struct stat parent; int fd = 0, rc = 0; FILE *logfile = NULL; char *parent_dir = NULL; char *filename_cp; static gboolean have_logfile = FALSE; if (filename == NULL && have_logfile == FALSE) { filename = "/var/log/pacemaker.log"; } if (filename == NULL) { return FALSE; /* Nothing to do */ } filename_cp = strdup(filename); /* Check the parent directory and attempt to open */ parent_dir = dirname(filename_cp); rc = stat(parent_dir, &parent); if (rc != 0) { crm_err("Directory '%s' does not exist: logging to '%s' is disabled", parent_dir, filename); free(filename_cp); return FALSE; } else if (parent.st_uid == geteuid() && (parent.st_mode & (S_IRUSR | S_IWUSR))) { /* all good - user */ logfile = fopen(filename, "a"); } else if (parent.st_gid == getegid() && (parent.st_mode & S_IXGRP)) { /* all good - group */ logfile = fopen(filename, "a"); } else { crm_err ("We (uid=%u, gid=%u) do not have permission to access '%s': logging to '%s' is disabled", geteuid(), getegid(), parent_dir, filename); free(filename_cp); return FALSE; } free(filename_cp); filename_cp = NULL; /* Check/Set permissions if we're root */ if (logfile && geteuid() == 0) { struct stat st; uid_t pcmk_uid = 0; gid_t pcmk_gid = 0; gboolean fix = FALSE; int logfd = fileno(logfile); rc = fstat(logfd, &st); if (rc < 0) { crm_perror(LOG_WARNING, "Cannot stat %s", filename); fclose(logfile); return FALSE; } crm_user_lookup(CRM_DAEMON_USER, &pcmk_uid, &pcmk_gid); if (st.st_gid != pcmk_gid) { /* Wrong group */ fix = TRUE; } else if ((st.st_mode & S_IRWXG) != (S_IRGRP | S_IWGRP)) { /* Not read/writable by the correct group */ fix = TRUE; } if (fix) { rc = fchown(logfd, pcmk_uid, pcmk_gid); if (rc < 0) { crm_warn("Cannot change the ownership of %s to user %s and gid %d", filename, CRM_DAEMON_USER, pcmk_gid); } rc = fchmod(logfd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (rc < 0) { crm_warn("Cannot change the mode of %s to rw-rw----", filename); } fprintf(logfile, "Set r/w permissions for uid=%d, gid=%d on %s\n", pcmk_uid, pcmk_gid, filename); if (fflush(logfile) < 0 || fsync(logfd) < 0) { crm_err("Couldn't write out logfile: %s", filename); } } } if (logfile) { fclose(logfile); } /* Now open with libqb */ fd = qb_log_file_open(filename); if (fd < 0) { crm_perror(LOG_WARNING, "Couldn't send additional logging to %s", filename); return FALSE; } crm_notice("Additional logging available in %s", filename); qb_log_ctl(fd, QB_LOG_CONF_ENABLED, QB_TRUE); /* Enable callsites */ crm_update_callsites(); have_logfile = TRUE; return TRUE; }
/** * \brief Measures the time to write once to a file. * * Only one process is active. It writes once to a file. * * Remark:<br> * With the <tt>O_DIRECT</tt> flag set, cache effects are minimized, because I/O * is done directly to/from user space buffers. The operation system's page * cache is bypassed. Under Linux 2.6 alignment to 512-byte boundaries is * required for buffer and file offset. Thus the following parameters should be * set in a SKaMPI input file: * - <tt>set_send_buffert_alignment (512)</tt> * - <tt>set_recv_buffert_alignment (512)</tt> * - <tt>switch_buffer_cycling_off ()</tt><br> * * <tt>O_DIRECT</tt> is only relevant if the POSIX-API is used for I/O. * * For more information please refer to the <tt>open ()</tt> man pages. * * \param[in] size size of memory buffer, i.e. number of <tt>MPI_BYTE</tt>s * \param[in] api POSIX-API or MPI-API for I/O accesses * \param[in] create_flag write into existing file (FALSE) or create it (TRUE) * \param[in] directio_flag open file with <tt>O_DIRECT</tt> flag to minimize * cache effects * * \return measured time */ double measure_MPI_IO_write_file_once (int size, char *api, int create_flag, int directio_flag){ double start_time = 1.0, end_time = 0.0; int open_flags; char *error_string; if (get_measurement_rank () == 0){ if (strcmp (api, POSIX_API) == 0){ if (directio_flag != 0) open_flags = O_WRONLY | O_DIRECT; else open_flags = O_WRONLY; errno = 0; if (create_flag == 0){ /* open existing file */ if ((io_fd = open (io_filename, open_flags)) < 0){ error_string = strerror (errno); error_with_abort (errno, "\nmeasure_MPI_IO_write_file_once (int %d, char * %s, int %d, int %d) failed." "\nCannot open local file (write only mode)." "\nError: %s\n", size, api, create_flag, directio_flag, error_string); } } else { /* open nonexisting file and create it */ if ((io_fd = open (io_filename, open_flags|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0){ error_string = strerror (errno); error_with_abort (errno, "\nmeasure_MPI_IO_write_file_once (int %d, char * %s, int %d, int %d) failed." "\nCannot open local file (write only mode)." "\nError: %s\n", size, api, create_flag, directio_flag, error_string); } } start_time = start_synchronization (); write (io_fd, get_send_buffer (), size); fsync (io_fd); end_time = MPI_Wtime (); close (io_fd); } else{ /* if strcmp (api, POSIX_API) != 0 */ if (create_flag == 0){ MPI_File_open (MPI_COMM_SELF, io_filename, MPI_MODE_WRONLY, MPI_INFO_NULL, &io_fh); } else{ /* if create_flag != 0*/ MPI_File_open (MPI_COMM_SELF, io_filename, MPI_MODE_WRONLY|MPI_MODE_CREATE, MPI_INFO_NULL, &io_fh); } MPI_File_set_view (io_fh, (MPI_Offset)0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL); start_time = start_synchronization (); MPI_File_write (io_fh, get_send_buffer (), size, MPI_BYTE, MPI_STATUS_IGNORE); MPI_File_sync (io_fh); end_time = MPI_Wtime (); MPI_File_close (&io_fh); } } else if (get_measurement_rank () != 0) { start_synchronization (); } stop_synchronization (); if (get_measurement_rank () == 0) return end_time - start_time; else return -1.0; }
virtual int run(int checkpoint) override { int local_checkpoint = 0; //Open file foo const int fd_foo = open(foo_path.c_str(), O_RDWR); if (fd_foo < 0) { return -1; } // system("stat /mnt/snapshot/foo"); /*-------------------Variant 1 ---------------------------*/ //unaligned offset and size less than a page //Fallocate from off 17000 of length 3000 if(fallocate(fd_foo, FALLOC_FL_KEEP_SIZE ,17000, 3000) < 0){ close(fd_foo); return -2; } //fsync file_foo int res = fsync(fd_foo); if (res < 0){ close(fd_foo); return -3; } // Make a user checkpoint here. Checkpoint must be 1 beyond this point // Beyond this point, the effect of falloc must be visible if (Checkpoint() < 0){ close(fd_foo); return -4; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 0; } //Expected output if checkpoint = 1 : Size = 16K, blocks == 40 (32 + 8) // system("stat /mnt/snapshot/foo"); /*-------------------Variant 2 ---------------------------*/ //aligned offset and size less than a page //Fallocate from off 24K of length 3000 if(fallocate(fd_foo, FALLOC_FL_KEEP_SIZE ,24576, 3000) < 0){ close(fd_foo); return -2; } //fsync file_foo res = fsync(fd_foo); if (res < 0){ close(fd_foo); return -3; } // Make a user checkpoint here. Checkpoint must be 2 beyond this point // Beyond this point, the effect of falloc must be visible if (Checkpoint() < 0){ close(fd_foo); return -4; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 0; } //Expected output if checkpoint = 2: size = 16K, blocks == 48 (40 + 8) // system("stat /mnt/snapshot/foo"); /*-------------------Variant 3 ---------------------------*/ //Aligned offset and size > a page //Fallocate from off 32K of length 8192 if(fallocate(fd_foo, FALLOC_FL_KEEP_SIZE , 32768, 8192) < 0){ close(fd_foo); return -2; } //fsync file_foo res = fsync(fd_foo); if (res < 0){ close(fd_foo); return -3; } // Make a user checkpoint here. Checkpoint must be 3 beyond this point // Beyond this point, the effect of falloc must be visible if (Checkpoint() < 0){ close(fd_foo); return -4; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 0; } //Expected output if checkpoint = 3: size = 16K, blocks == 64 (48 + 16) // system("stat /mnt/snapshot/foo"); /*-------------------Variant 4 ---------------------------*/ //unaligned offset and size less than a page //Fzero from off 42000 of length 3000 if(fallocate(fd_foo, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE ,42000, 3000) < 0){ close(fd_foo); return -2; } //fsync file_foo res = fsync(fd_foo); if (res < 0){ close(fd_foo); return -3; } // Make a user checkpoint here. Checkpoint must be 4 beyond this point // Beyond this point, the effect of falloc must be visible if (Checkpoint() < 0){ close(fd_foo); return -4; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 0; } //Expected output if checkpoint = 4 : Size = 16K, blocks == 72 (64 + 8) // system("stat /mnt/snapshot/foo"); /*-------------------Variant 5 ---------------------------*/ //aligned offset and size less than a page //Fzero from off 48K of length 3000 if(fallocate(fd_foo, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE ,49152, 3000) < 0){ close(fd_foo); return -2; } //fsync file_foo res = fsync(fd_foo); if (res < 0){ close(fd_foo); return -3; } // Make a user checkpoint here. Checkpoint must be 5 beyond this point // Beyond this point, the effect of falloc must be visible if (Checkpoint() < 0){ close(fd_foo); return -4; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 0; } //Expected output if checkpoint = 5: size = 16K, blocks == 80 (72 + 8) // system("stat /mnt/snapshot/foo"); /*-------------------Variant 6 ---------------------------*/ //Aligned offset and size > a page //Fzero from off 52K of length 8192 if(fallocate(fd_foo, FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE , 53248, 8192) < 0){ close(fd_foo); return -2; } //fsync file_foo res = fsync(fd_foo); if (res < 0){ close(fd_foo); return -3; } // Make a user checkpoint here. Checkpoint must be 6 beyond this point // Beyond this point, the effect of falloc must be visible if (Checkpoint() < 0){ close(fd_foo); return -4; } local_checkpoint += 1; if (local_checkpoint == checkpoint) { return 1; } //Expected output if checkpoint = 6: size = 16K, blocks == 96 (80 + 16) // system("stat /mnt/snapshot/foo"); //Close open files close(fd_foo); return 0; }
int main(int argc, char *argv[]) { int fd,pos_io; char s[taille_bloc+1]; // +1 pour pouvoir ajouter le caractère '\0' de fin de chaine long nb_char=0; long taille_nombre; long nb_char_ecrits_total=0; long nb_char_lus_total=0; int i; long nb_nombre; int nb_max=100; char *device_name; char str_nombre[100]; int retval; unsigned int taille; char rep='n'; long nb_car_a_lire; int bad=0, nb_ecrits; if (argc != 2) { fprintf(stderr, "usage : %s <nom du dev>\n", argv[0]); return 1; } device_name = argv[1]; printf("device name =%s\n", device_name); if ((fd = open(device_name,O_RDWR)) <0) { printf("Erreur à l'ouverture du device %s",device_name); exit(-1); } printf("Ouverture de %s terminée\n",device_name); printf("Test taille\n"); retval = ioctl(fd,BLKGETSIZE,&taille); if (retval !=0) printf("Erreur dans le ioctl BLKGETSIZE, taille =%d\n",taille); else printf("Ioctl BLKGETSIZE, taille =%d\n",taille); printf("Test d'écriture et de lecture\nEntrez le nombre d'entier à écrire : "); scanf("%ld",&nb_nombre); printf("Voulez-vous un affichage de ce qui est écrit et de ce qui est relu ? (o/n) : "); scanf("\n%c",&rep); printf("\n"); printf("Ecriture de la chaine 1 2 3 4 ... %ld sur %s\n",nb_nombre,device_name); pos_io=lseek(fd,0,SEEK_SET); for (i=1;i<=nb_nombre;i++) { taille_nombre=sprintf(str_nombre,"%ld ",i); nb_ecrits = write(fd,str_nombre,taille_nombre); if (nb_ecrits != taille_nombre) { fprintf(stderr,"erreur à l'écriture de '%s', return = %d\n", str_nombre, nb_ecrits); } nb_char_ecrits_total+=taille_nombre; str_nombre[taille_nombre]='\0'; if (rep=='o') printf("%s",str_nombre); } if (rep=='o') printf(".\n"); printf("Ecriture terminée : %ld caractères écrits\n",nb_char_ecrits_total); printf("\n"); printf("Test de lecture : par blocs de %ld caractères\n",taille_bloc); lseek(fd,0,SEEK_SET); for (i=0;i<nb_char_ecrits_total;i+=taille_bloc) { if (i+taille_bloc>nb_char_ecrits_total) nb_car_a_lire=nb_char_ecrits_total-i; else nb_car_a_lire=taille_bloc; nb_char=read(fd,s,nb_car_a_lire); nb_char_lus_total+=nb_char; s[nb_char]='\0'; if (rep=='o') printf("%s",s); } if (rep=='o') printf(".\n"); printf("Lecture terminée : %ld caractères lus\n",nb_char_lus_total); printf("\n"); printf("fsync du fichier\n"); retval = fsync(fd); if (retval == 0) printf("fsync ok\n"); else fprintf(stderr, "erreur fsync\n"); printf("\n"); printf("Test de lecture : lecture des %ld entiers et vérif que chaque entier est correct\n",nb_nombre); lseek(fd,0,SEEK_SET); for (i=1;i<nb_nombre;i++) { taille_nombre=sprintf(str_nombre,"%ld ",i); nb_char=read(fd,s,taille_nombre); if (nb_char!=taille_nombre) { printf("Erreur dans la lecture du nombre %ld : " "taille voulue = %ld, taille lue = %ld\n", i,taille_nombre,nb_char); bad=1; } else { s[nb_char]='\0'; str_nombre[nb_char]='\0'; if (strcmp(s,str_nombre)!=0) { printf("Erreur dans la lecture du nombre %ld : " "str voulue = <%s>, str obtenue = <%s>\n", i,str_nombre,s); bad=1; } } if (bad) break; } printf("Lecture de contrôle terminée : "); if (bad == 0) printf("** SUCCES ! **\n"); else printf("** ECHEC ! **\n"); printf("\n"); printf("Fermeture du fichier\n"); if (close(fd) !=0) { printf("Erreur détectée à la fermeture"); } printf("Fin du programme\n"); return(0); }
// Write a memory buffer to 'target' partition, a string of the form // "MTD:<partition>[:...]" or "EMMC:<partition_device>:". Return 0 on // success. int WriteToPartition(unsigned char* data, size_t len, const char* target) { char* copy = strdup(target); const char* magic = strtok(copy, ":"); enum PartitionType type; if (strcmp(magic, "MTD") == 0) { type = MTD; } else if (strcmp(magic, "EMMC") == 0) { type = EMMC; } else { printf("WriteToPartition called with bad target (%s)\n", target); return -1; } const char* partition = strtok(NULL, ":"); if (partition == NULL) { printf("bad partition target name \"%s\"\n", target); #if 1 free(copy); #endif return -1; } char *dev_path = get_partition_path(partition); partition = dev_path; switch (type) { case MTD: if (!mtd_partitions_scanned) { mtd_scan_partitions(); mtd_partitions_scanned = 1; } const MtdPartition* mtd = mtd_find_partition_by_name(partition); if (mtd == NULL) { printf("mtd partition \"%s\" not found for writing\n", partition); #if 1 free(copy); free(partition); #endif return -1; } MtdWriteContext* ctx = mtd_write_partition(mtd); if (ctx == NULL) { printf("failed to init mtd partition \"%s\" for writing\n", partition); #if 1 free(copy); free(partition); #endif return -1; } size_t written = mtd_write_data(ctx, (char*)data, len); if (written != len) { printf("only wrote %zu of %zu bytes to MTD %s\n", written, len, partition); mtd_write_close(ctx); #if 1 free(copy); free(partition); #endif return -1; } if (mtd_erase_blocks(ctx, -1) < 0) { printf("error finishing mtd write of %s\n", partition); mtd_write_close(ctx); #if 1 free(copy); free(partition); #endif return -1; } if (mtd_write_close(ctx)) { printf("error closing mtd write of %s\n", partition); #if 1 free(copy); free(partition); #endif return -1; } break; case EMMC: { size_t start = 0; int success = 0; int fd = open(partition, O_RDWR | O_SYNC); if (fd < 0) { printf("failed to open %s: %s\n", partition, strerror(errno)); return -1; } int attempt; for (attempt = 0; attempt < 2; ++attempt) { if (TEMP_FAILURE_RETRY(lseek(fd, start, SEEK_SET)) == -1) { printf("failed seek on %s: %s\n", partition, strerror(errno)); close(fd); return -1; } while (start < len) { size_t to_write = len - start; if (to_write > 1<<20) to_write = 1<<20; ssize_t written = TEMP_FAILURE_RETRY(write(fd, data+start, to_write)); if (written == -1) { printf("failed write writing to %s: %s\n", partition, strerror(errno)); close(fd); return -1; } start += written; } if (fsync(fd) != 0) { printf("failed to sync to %s (%s)\n", partition, strerror(errno)); close(fd); return -1; } if (close(fd) != 0) { printf("failed to close %s (%s)\n", partition, strerror(errno)); return -1; } fd = open(partition, O_RDONLY); if (fd < 0) { printf("failed to reopen %s for verify (%s)\n", partition, strerror(errno)); return -1; } // drop caches so our subsequent verification read // won't just be reading the cache. sync(); int dc = open("/proc/sys/vm/drop_caches", O_WRONLY); if (TEMP_FAILURE_RETRY(write(dc, "3\n", 2)) == -1) { printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno)); } else { printf(" caches dropped\n"); } close(dc); sleep(1); // verify if (TEMP_FAILURE_RETRY(lseek(fd, 0, SEEK_SET)) == -1) { printf("failed to seek back to beginning of %s: %s\n", partition, strerror(errno)); close(fd); return -1; } unsigned char buffer[4096]; start = len; size_t p; for (p = 0; p < len; p += sizeof(buffer)) { size_t to_read = len - p; if (to_read > sizeof(buffer)) to_read = sizeof(buffer); size_t so_far = 0; while (so_far < to_read) { ssize_t read_count = TEMP_FAILURE_RETRY(read(fd, buffer+so_far, to_read-so_far)); if (read_count == -1) { printf("verify read error %s at %zu: %s\n", partition, p, strerror(errno)); close(fd); return -1; } if ((size_t)read_count < to_read) { printf("short verify read %s at %zu: %zd %zu %s\n", partition, p, read_count, to_read, strerror(errno)); } so_far += read_count; } if (memcmp(buffer, data+p, to_read)) { printf("verification failed starting at %zu\n", p); start = p; break; } } if (start == len) { printf("verification read succeeded (attempt %d)\n", attempt+1); success = true; break; } } if (!success) { printf("failed to verify after all attempts\n"); close(fd); return -1; } if (close(fd) != 0) { printf("error closing %s (%s)\n", partition, strerror(errno)); return -1; } sync(); break; } } free(copy); return 0; }
void read_perf_test(unsigned long kilo64,long long reclen,long long *data1,long long *data2) { double starttime2; double compute_val = (double)0; double readtime[2]; double walltime[2], cputime[2]; long long j; long long traj_size; unsigned long i,numrecs64,traj_offset; unsigned long lock_offset=0; long long Index = 0; unsigned long long readrate[2]; unsigned long filebytes64; volatile char *buffer1; char *nbuff; int fd,open_flags; int test_foo,ltest; long wval; double qtime_start,qtime_stop; double hist_time; unsigned long r_traj_ops_completed=0; unsigned long r_traj_bytes_completed=0; long long *gc=0; char *filename = "/mnt/ramdisk/test1"; size_t len = reclen; struct timespec start, end; long long time; hist_time=qtime_start=qtime_stop=0; traj_offset=0; test_foo=0; numrecs64 = (kilo64*1024)/reclen; open_flags = O_RDONLY; filebytes64 = numrecs64*reclen; fd = 0; // mainbuffer = (char *)malloc(4 * 1024 * 4096); /* * begin real testing */ ltest=3; printf("%s: filename %s, test %d, reclen %lld, numrecs64 %llu, filebytes64 %llu\n", __func__, filename, ltest, reclen, numrecs64, filebytes64); // fd = open(filename, open_flags,0640); for( j=0; j<ltest; j++ ) { // lseek(fd,0,SEEK_SET); if((fd = open(filename, open_flags,0))<0) { printf("\nCan not open temporary file %s for read\n",filename); perror("open"); exit(58); } printf("fd: %d, reclen %lu\n", fd, reclen); fsync(fd); /* * Need to prime the instruction cache & TLB */ nbuff=mainbuffer; // read(fd, (void *)nbuff, (size_t)reclen); // if(fetchon) // fetchit(nbuff,reclen); if(read(fd, (void *)nbuff, 4096) != reclen) { #ifdef _64BIT_ARCH_ printf("\nError reading block %d %llx\n", 0, (unsigned long long)nbuff); #else printf("\nError reading block %d %lx\n", 0, (long)nbuff); #endif perror("read"); exit(60); } lseek(fd,0,SEEK_SET); nbuff=mainbuffer; starttime2 = time_so_far(); compute_val=(double)0; r_traj_ops_completed=0; r_traj_bytes_completed=0; clock_gettime(CLOCK_MONOTONIC, &start); for(i=0; i<numrecs64; i++) { wval=read((int)fd, (void*)nbuff, 4096); if(wval != reclen) { printf("\nError reading block %lld %llx\n", i, (unsigned long long)nbuff); perror("read"); exit(61); } r_traj_ops_completed++; r_traj_bytes_completed+=reclen; } clock_gettime(CLOCK_MONOTONIC, &end); time = (end.tv_sec - start.tv_sec) * 1e9 + (end.tv_nsec - start.tv_nsec); printf("%lld ns\n", time); readtime[j] = ((time_so_far() - starttime2))-compute_val; if(readtime[j] < (double).000001) { readtime[j]= (double)0.000001; } fsync(fd); close(fd); } filebytes64=r_traj_bytes_completed; printf("%s: completed %llu\n", __func__, filebytes64); for(j=0;j<ltest;j++) { readrate[j] = (unsigned long long) ((double) filebytes64 / readtime[j]); printf("%s: ltest %d readrate %llu\n", __func__, j, readrate[j]); } }
/// Synchronizes the file's data and status with the disk. void fstream::sync (void) { if (fsync (m_fd)) set_and_throw (badbit | failbit, "sync"); }