static void do_quiesce_test(uint32_t num_objs, uint32_t iters, uint32_t num_snaps) { struct ZS_thread_state *thd_state; int i = 0; pthread_t thread_id; // uint32_t iter_print_cnt = 0; printf("============================= Snapshot Quiesce Test =========================\n"); fflush(stdout); ZSInitPerThreadState(zs_state, &thd_state); open_stuff(thd_state, "cntr_4"); snapshot_cnt = 0; objs_processed = num_objs; pthread_create(&thread_id, NULL, (void *)write_data, (void *)(uint64_t)iters); for (i = 0; i < num_snaps; i++) { create_snapshot(thd_state, i); sched_yield(); } pthread_join(thread_id, NULL); for (i = 0; i < num_snaps; i++) { if ((snap_seqnos[i] - snap_seqnos[i - 1]) != 1 || (snap_seqnos[i] - snap_seqnos[i - 1]) != num_objs) { printf("IO is not quiesced when snapshot is in progress\n"); } } free_stuff(thd_state); ZSReleasePerThreadState(&thd_state); }
/* * Get the `snapshot` for the specified packed_ref_store, creating and * populating it if it hasn't been read before or if the file has been * changed (according to its `validity` field) since it was last read. * On the other hand, if we hold the lock, then assume that the file * hasn't been changed out from under us, so skip the extra `stat()` * call in `stat_validity_check()`. This function does *not* increase * the snapshot's reference count on behalf of the caller. */ static struct snapshot *get_snapshot(struct packed_ref_store *refs) { if (!is_lock_file_locked(&refs->lock)) validate_snapshot(refs); if (!refs->snapshot) refs->snapshot = create_snapshot(refs); return refs->snapshot; }
static void do_rw_test(uint32_t num_objs, uint32_t iters, uint32_t num_snaps) { struct ZS_thread_state *thd_state; int i; uint32_t iter_print_cnt = 0; printf("============================= Snapshot Read/Write Test =========================\n"); fflush(stdout); ZSInitPerThreadState(zs_state, &thd_state); open_stuff(thd_state, "cntr_1"); snapshot_cnt = 0; /* Write the contents of snapshots */ for (i = 0; i < num_snaps; i++) { printf("Iter: %u: %s %u objects\n", ++iter_print_cnt, (i%2) ? "Writing": "MPutting", num_objs); fflush(stdout); if ((i % 2) == 0) { do_mput(thd_state, 0, num_objs, i, 0); } else { do_write(thd_state, 0, num_objs, i, 0); } printf("Creating Snapshot %u\n", i); fflush(stdout); create_snapshot(thd_state, i); } /* Write the remaining iterations */ for (;i < iters; i++) { printf("Iter: %u: %s %u objects\n", ++iter_print_cnt, (i%2) ? "Writing": "MPutting", num_objs); fflush(stdout); if ((i % 2) == 0) { do_mput(thd_state, 0, num_objs, i, 0); } else { do_write(thd_state, 0, num_objs, i, 0); } } do_read_verify(thd_state, 0, num_objs, ZS_SUCCESS); printf("Doing range query for latest update\n"); do_read_verify_snapshot(thd_state, 0, num_objs, iters-1, 20); for (i = 0; i < num_snaps; i++) { do_read_verify_snapshot(thd_state, 0, num_objs, i, 20); } free_stuff(thd_state); ZSReleasePerThreadState(&thd_state); }
static int plooptool_snapshot(int argc, char **argv) { int i, ret; char *device = NULL; int syncfs = 0; struct ploop_snapshot_param param = {}; while ((i = getopt(argc, argv, "Fd:u:")) != EOF) { switch (i) { case 'd': device = optarg; break; case 'F': syncfs = 1; break; case 'u': param.guid = parse_uuid(optarg); if (!param.guid) return SYSEXIT_PARAM; break; default: usage_snapshot(); return SYSEXIT_PARAM; } } argc -= optind; argv += optind; if (argc != 1) { usage_snapshot(); return SYSEXIT_PARAM; } if (is_xml_fname(argv[0])) { struct ploop_disk_images_data *di; ret = ploop_open_dd(&di, argv[0]); if (ret) return ret; ret = ploop_create_snapshot(di, ¶m); ploop_close_dd(di); } else { if (!device) { usage_snapshot(); return SYSEXIT_PARAM; } ret = create_snapshot(device, argv[0], syncfs); } return ret; }
/* * Create a new subvolume below @parent. This is largely modeled after * sys_mkdirat and vfs_mkdir, but we only do a single component lookup * inside this filesystem so it's quite a bit simpler. */ static noinline int btrfs_mksubvol(struct path *parent, char *name, int namelen, struct btrfs_root *snap_src) { struct inode *dir = parent->dentry->d_inode; struct dentry *dentry; int error; mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); dentry = lookup_one_len(name, parent->dentry, namelen); error = PTR_ERR(dentry); if (IS_ERR(dentry)) goto out_unlock; error = -EEXIST; if (dentry->d_inode) goto out_dput; error = mnt_want_write(parent->mnt); if (error) goto out_dput; error = btrfs_may_create(dir, dentry); if (error) goto out_drop_write; down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); if (btrfs_root_refs(&BTRFS_I(dir)->root->root_item) == 0) goto out_up_read; if (snap_src) { error = create_snapshot(snap_src, dentry, name, namelen); } else { error = create_subvol(BTRFS_I(dir)->root, dentry, name, namelen); } if (!error) fsnotify_mkdir(dir, dentry); out_up_read: up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); out_drop_write: mnt_drop_write(parent->mnt); out_dput: dput(dentry); out_unlock: mutex_unlock(&dir->i_mutex); return error; }
int main ( int argc , char *argv [] ) { SNAPSHOT_HEADER header; DUMPBLOCKV10 block; unsigned int filelen = 0; unsigned int sections; void *module_base = 0x10000000; void *data; FILE *f1; FILE *f2; /* Chequeo los paramentros */ if ( ( argc != 3 ) && ( argc != 4 ) ) { printf ( "\nfsnap v1.1\n" ); printf ( "Created by Nicolas A. Economou\n" ); printf ( "Core Security Technologies, Buenos Aires, Argentina (2015)\n" ); printf ( "\nUse: fsnap input_file output_file [-force_base]\n" ); return ( 0 ); } /* Si quiero que CARGUE el MODULO en la BASE ORIGINAL */ if ( argc == 4 ) { /* Si NO es el comando CORRECTO */ if ( strcmp ( argv [ 3 ] , "-force_base" ) != 0 ) { printf ( "\nUse: fsnap input_file output_file [-force_base]\n" ); return ( 0 ); } } /* Si el FILE existe */ if ( is_filename_ok ( argv [ 1 ] ) == TRUE ) { /* Si es la PRIMERA CORRIDA */ if ( argc == 3 ) { /* Si pude cargar el MODULO en MEMORIA */ if ( is_loadable_module ( argv [ 1 ] , FALSE , &module_base ) == TRUE ) { /* Si la BASE es DISTINTA de donde ESTA CARGADO */ if ( get_module_base ( argv [ 1 ] ) != ( void * ) module_base ) { /* Si PUDE CARGAR el MODULO en la BASE */ if ( get_valid_loading ( argv [ 1 ] , argv [ 2 ] ) == TRUE ) { /* Salgo OK */ return ( 1 ); } } /* Creo un SNAPSHOT del MODULO */ create_snapshot ( argv [ 1 ] , module_base , argv [ 2 ] ); } /* Si el file NO ES LOADABLE ( puede ser un file de otro OS, un shellcode, etc ) */ else { /* Creo el OUTPUT FILE */ f2 = fopen ( argv [ 2 ] , "wb" ); /* Si el file NO pudo ser creado */ if ( f2 == NULL ) { printf ( "Error: Invalid output_file\n" ); return ( 0 ); } /* Abro el file */ f1 = fopen ( argv [ 1 ] , "rb" ); /* Obtengo el size del file */ filelen = get_file_len ( f1 ); /* Seteo el header del file */ header.sig = 0x70616E73; header.version = 1; header.flags = 0x80000000; // Fake memory dump header.blockcount = 1; fwrite ( &header , sizeof ( header ) , 1 , f2 ); /* Seteo la UNICA SECCION del SNAPSHOT */ block.BaseAddress = 0x10000000; block.RegionSize = filelen; block.Protect = READABLE | WRITABLE | EXECUTABLE; fwrite ( &block , sizeof ( block ) , 1 , f2 ); /* Dumpeo la data */ data = malloc ( filelen ); fread ( data , filelen , 1 , f1 ); fwrite ( data , filelen , 1 , f2 ); /* Mensaje al usuario */ printf ( "[x] Setting ARBITRARY image base at: %.8x\n" , block.BaseAddress ); /* Cierro el file */ fclose ( f1 ); /* Cierro el file */ fclose ( f2 ); } } /* Si es una CORRIDA AUXILIAR (para intentar MAPEAR en la BASE) */ else { /* Si pude cargar el MODULO en MEMORIA */ if ( is_loadable_module ( argv [ 1 ] , TRUE , &module_base ) == TRUE ) { /* Creo un SNAPSHOT del MODULO */ create_snapshot ( argv [ 1 ] , module_base , argv [ 2 ] ); /* Retorno OK */ return ( 1 ); } /* Si NO se PUDO MAPEAR en la BASE */ else { /* Salgo con ERROR */ return ( 0 ); } } } /* Si hubo algun ERROR */ else { printf ( "Error: Invalid input_file\n" ); return ( 0 ); } return ( 1 ); }
int main(int argc, char *argv[]) { if(argc<2) { std::cout << "Not enough parameters" << std::endl; return 1; } std::string cmd=argv[1]; std::string backupfolder=getBackupfolderPath(); if(backupfolder.empty()) { std::cout << "Backupfolder not set" << std::endl; return 1; } #ifndef _WIN32 if(seteuid(0)!=0) { std::cout << "Cannot become root user" << std::endl; return 1; } #endif if(cmd=="create") { if(argc<4) { std::cout << "Not enough parameters for create" << std::endl; return 1; } std::string clientname=handleFilename(argv[2]); std::string name=handleFilename(argv[3]); std::string subvolume_folder=backupfolder+os_file_sepn()+clientname+os_file_sepn()+name; return create_subvolume(subvolume_folder)?0:1; } else if(cmd=="snapshot") { if(argc<5) { std::cout << "Not enough parameters for snapshot" << std::endl; return 1; } std::string clientname=handleFilename(argv[2]); std::string src_name=handleFilename(argv[3]); std::string dst_name=handleFilename(argv[4]); std::string subvolume_src_folder=backupfolder+os_file_sepn()+clientname+os_file_sepn()+src_name; std::string subvolume_dst_folder=backupfolder+os_file_sepn()+clientname+os_file_sepn()+dst_name; return create_snapshot(subvolume_src_folder, subvolume_dst_folder)?0:1; } else if(cmd=="remove") { if(argc<4) { std::cout << "Not enough parameters for remove" << std::endl; return 1; } std::string clientname=handleFilename(argv[2]); std::string name=handleFilename(argv[3]); std::string subvolume_folder=backupfolder+os_file_sepn()+clientname+os_file_sepn()+name; return remove_subvolume(subvolume_folder)?0:1; } else if(cmd=="test") { std::string clientdir=backupfolder+os_file_sepn()+"testA54hj5luZtlorr494"; if(os_create_dir(clientdir)) { if(!create_subvolume(clientdir+os_file_sepn()+"A") ) { std::cout << "Creating test subvolume failed" << std::endl; os_remove_dir(clientdir); return 1; } bool suc=true; if(!create_snapshot(clientdir+os_file_sepn()+"A", clientdir+os_file_sepn()+"B") ) { std::cout << "Creating test snapshot failed" << std::endl; suc=false; } if(suc) { writestring("test", clientdir+os_file_sepn()+"A"+os_file_sepn()+"test"); if(!os_create_hardlink(clientdir+os_file_sepn()+"B"+os_file_sepn()+"test", clientdir+os_file_sepn()+"A"+os_file_sepn()+"test", true, NULL)) { std::cout << "Cross subvolume reflink failed" << std::endl; suc=false; } if(getFile(clientdir+os_file_sepn()+"B"+os_file_sepn()+"test")!="test") { std::cout << "Cannot read reflinked file" << std::endl; suc=false; } } if(!remove_subvolume(clientdir+os_file_sepn()+"A") ) { std::cout << "Removing subvolume A failed" << std::endl; suc=false; } if(!remove_subvolume(clientdir+os_file_sepn()+"B") ) { std::cout << "Removing subvolume B failed" << std::endl; suc=false; } if(!os_remove_dir(clientdir)) { std::cout << "Removing test clientdir failed" << std::endl; return 1; } if(!suc) { return 1; } } else { std::cout << "Creating test clientdir \"" << clientdir << "\" failed" << std::endl; return 1; } return 0; } else if(cmd=="issubvolume") { if(argc<4) { std::cout << "Not enough parameters for issubvolume" << std::endl; return 1; } std::string clientname=handleFilename(argv[2]); std::string name=handleFilename(argv[3]); std::string subvolume_folder=backupfolder+os_file_sepn()+clientname+os_file_sepn()+name; return is_subvolume(subvolume_folder)?0:1; } else { std::cout << "Command not found" << std::endl; return 1; }
int main(int argc, char **argv) { // Record the start time of the program time_t start_time = time(NULL); // Extract the input parameters from the command line arguments // Number of columns in the grid (default = 1,000) num_cols = (argc > 1) ? atoi(argv[1]) : 1000; // Number of rows in the grid (default = 1,000) num_rows = (argc > 2) ? atoi(argv[2]) : 1000; // Number of iterations to simulate (default = 100) iterations = (argc > 3) ? atoi(argv[3]) : 100; // Number of threads thread_count= (argc > 4) ? atoi(argv[4]) : 2; //Initialize barrier and barrier2 //If any error, exit. if(pthread_barrier_init(&barrier, NULL, thread_count)){ printf("Unable to init a barrier\n"); return -1; } if(pthread_barrier_init(&barrier2, NULL, thread_count)){ printf("Unable to init a barrier\n"); return -1; } //Declare pthread attributes and ids. int thread_ids[thread_count]; pthread_t threads[thread_count]; pthread_attr_t attr; //Declare cpu_set object to be used for CPU affinity setting cpu_set_t cores; //Initialize and set pthread attribute as joinable //Only threads created joinable can be joined, other the thread is detached. pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // Output the simulation parameters printf("Grid: %dx%d, Iterations: %d\n", num_cols, num_rows, iterations); // We allocate two arrays: one for the current time step and one for the next time step. // At the end of each iteration, we switch the arrays in order to avoid copying. // The arrays are allocated with an extra surrounding layer which contains // the immutable boundary conditions (this simplifies the logic in the inner loop). cells[0] = allocate_cells(num_cols + 2, num_rows + 2); cells[1] = allocate_cells(num_cols + 2, num_rows + 2); cur_cells_index = 0; next_cells_index = 1; // Initialize the interior (non-boundary) cells to their initial value. // Note that we only need to initialize the array for the current time // step, since we will write to the array for the next time step // during the first iteration. initialize_cells(cells[0], num_cols, num_rows); // Set the immutable boundary conditions in both copies of the array int x, y, i; for (x = 1; x <= num_cols; x++) cells[0][0][x] = cells[1][0][x] = TOP_BOUNDARY_VALUE; for (x = 1; x <= num_cols; x++) cells[0][num_rows + 1][x] = cells[1][num_rows + 1][x] = BOTTOM_BOUNDARY_VALUE; for (y = 1; y <= num_rows; y++) cells[0][y][0] = cells[1][y][0] = LEFT_BOUNDARY_VALUE; for (y = 1; y <= num_rows; y++) cells[0][y][num_cols + 1] = cells[1][y][num_cols + 1] = RIGHT_BOUNDARY_VALUE; for (i = 0; i < thread_count; i++) { thread_ids[i] = i; //For each new thread to create, first removes all cores from cores cpu_set_t object. CPU_ZERO(&cores); //Using thread id module the max core number, add corresponding core to the cpu set. CPU_SET(i % MAXCORE, &cores); //Set the attr for this thread to reflect the core on which to bind it. int status = pthread_attr_setaffinity_np(&attr,sizeof(cpu_set_t),&cores); if (status != 0) { printf("Could not set CPU affinity for thread %d\n",i); exit(EXIT_FAILURE); } //Create thread and bind to the core contained in cpu_set_t cores. status = pthread_create(&threads[i], &attr, PartialHeatPlate, (void*) &thread_ids[i]); if (status != 0) { printf("Could not create some pthreads\n"); exit(EXIT_FAILURE); } } // wait for the threads to finish for (i = 0; i < thread_count; i++) { pthread_join(threads[i], NULL); } // Output a snapshot of the final state of the plate int final_cells = (iterations % 2 == 0) ? 0 : 1; create_snapshot(cells[final_cells], num_cols, num_rows, iterations); // Compute and output the execution time time_t end_time = time(NULL); printf("\nExecution time: %d seconds\n", (int) difftime(end_time, start_time)); pthread_attr_destroy(&attr); return 0; }
int do_create_snapshot(struct ploop_disk_images_data *di, const char *guid, const char *snap_dir, const char *cbt_uuid, int flags) { int ret, rc; int fd; char dev[64]; char snap_guid[UUID_SIZE]; char top_guid[UUID_SIZE]; char file_guid[UUID_SIZE]; char fname[PATH_MAX]; const char *prev_fname = NULL; char conf[PATH_MAX]; char conf_tmp[PATH_MAX]; int online = 0; int temporary = flags & SNAP_TYPE_TEMPORARY; int n; off_t size; __u32 blocksize; int version; uuid_t u; const __u8 *cbt_u = NULL; if (cbt_uuid != NULL) { ploop_log(0, "Create snapshot CBT uuid=%s", cbt_uuid); if (uuid_parse(cbt_uuid, u)) { ploop_log(-1, "Incorrect cbt uuid is specified %s", cbt_uuid); return SYSEXIT_PARAM; } cbt_u = u; } if (guid != NULL && !is_valid_guid(guid)) { ploop_err(0, "Incorrect guid %s", guid); return SYSEXIT_PARAM; } if (is_old_snapshot_format(di)) return SYSEXIT_PARAM; ret = gen_uuid_pair(snap_guid, sizeof(snap_guid), file_guid, sizeof(file_guid)); if (ret) return ret; if (di->vol && di->vol->parent) { ret = ploop_uuid_generate(top_guid, sizeof(top_guid)); if (ret) return ret; } else strcpy(top_guid, TOPDELTA_UUID); if (guid != NULL) { if (find_snapshot_by_guid(di, guid) != -1) { ploop_err(0, "The snapshot %s already exist", guid); return SYSEXIT_PARAM; } strcpy(snap_guid, guid); } n = get_snapshot_count(di); if (n == -1) { return SYSEXIT_PARAM; } else if (n > 128-2) { /* The number of images limited by 128 so the snapshot limit 128 - base_image - one_reserverd */ ploop_err(errno, "Unable to create a snapshot." " The maximum number of snapshots (%d) has been reached", n-1); return SYSEXIT_PARAM; } rc = ploop_find_dev_by_dd(di, dev, sizeof(dev)); if (rc == -1) return SYSEXIT_SYS; if (rc == 0) { if (flags & SNAP_TYPE_OFFLINE) { ret = get_image_param_online(dev, &size, &blocksize, &version); } else { online = 1; ret = complete_running_operation(di, dev); } if (ret) return ret; } else { ret = get_image_param_offline(di, di->top_guid, &size, &blocksize, &version); if (ret == SYSEXIT_OPEN && errno == EBUSY) { /* repair top delta */ char *topdelta[] = {find_image_by_guid(di, di->top_guid), NULL}; blocksize = di->blocksize; ret = check_deltas(di, topdelta, 0, &blocksize, NULL); if (ret) return ret; ret = get_image_param_offline(di, di->top_guid, &size, &blocksize, &version); } if (ret) return ret; } ret = merge_temporary_snapshots(di); if (ret) return ret; if (snap_dir != NULL) { char *name; char *dir; dir = realpath(snap_dir, NULL); if (dir == NULL) { ploop_err(errno, "Error in realpath(%s)", snap_dir); return SYSEXIT_CREAT; } name = strrchr(di->images[0]->file, '/'); if (name != NULL) name++; else name = di->images[0]->file; snprintf(fname, sizeof(fname), "%s/%s.%s", dir, name, file_guid); free(dir); } else snprintf(fname, sizeof(fname), "%s.%s", di->images[0]->file, file_guid); prev_fname = find_image_by_guid(di, di->top_guid); if (prev_fname == NULL) { ploop_err(0, "Unable to find image by uuid %s", di->top_guid); return SYSEXIT_PARAM; } ploop_di_change_guid(di, di->top_guid, snap_guid); if (temporary) ploop_di_set_temporary(di, snap_guid); ret = ploop_di_add_image(di, fname, top_guid, snap_guid); if (ret) return ret; get_disk_descriptor_fname(di, conf, sizeof(conf)); snprintf(conf_tmp, sizeof(conf_tmp), "%s.tmp", conf); ret = ploop_store_diskdescriptor(conf_tmp, di); if (ret) return ret; if (!online) { // offline snapshot ret = 0; fd = create_snapshot_delta(fname, blocksize, size, version); if (fd < 0) { ret = SYSEXIT_CREAT; goto err; } close(fd); if (cbt_u != NULL) ret = write_empty_cbt_to_image(fname, prev_fname, cbt_u); else if (di->mode != PLOOP_RAW_MODE) { if (rc == 0) ret = cbt_dump(di, dev, fname); else ret = ploop_move_cbt(fname, prev_fname); } if (ret) goto err; } else { // Always sync fs ret = create_snapshot(dev, fname, 1, cbt_u, prev_fname); if (ret) goto err; } if (rename(conf_tmp, conf)) { ploop_err(errno, "Can't rename %s %s", conf_tmp, conf); ret = SYSEXIT_RENAME; } if (ret && !online && unlink(fname)) ploop_err(errno, "Can't unlink %s", fname); ploop_log(0, "ploop %s %s has been successfully created", get_snap_str(temporary), snap_guid); err: if (ret && unlink(conf_tmp)) ploop_err(errno, "Can't unlink %s", conf_tmp); return ret; }
int main(int argc, char *argv[]) { if(argc<2) { std::cout << "Not enough parameters" << std::endl; return 1; } std::string cmd; int mode = 0; if((std::string)argv[1]!="test") { if(argc<3) { std::cout << "Not enough parameters" << std::endl; return 1; } cmd=argv[2]; mode=atoi(argv[1]); } else { cmd=argv[1]; } std::string backupfolder=getBackupfolderPath(mode); if(backupfolder.empty()) { if(mode==mode_btrfs) { std::cout << "Backupfolder not set" << std::endl; } else if(mode==mode_zfs) { std::cout << "ZFS image dataset not set" << std::endl; } else if(mode==mode_zfs_file) { std::cout << "ZFS file dataset not set" << std::endl; } else { std::cout << "Unknown mode: " << mode << std::endl; } return 1; } if(cmd!="test" && mode==mode_zfs_file) { mode=mode_zfs; } #ifndef _WIN32 if(seteuid(0)!=0) { std::cout << "Cannot become root user" << std::endl; return 1; } #endif if(cmd=="create") { if(argc<5) { std::cout << "Not enough parameters for create" << std::endl; return 1; } std::string clientname=handleFilename(argv[3]); std::string name=handleFilename(argv[4]); std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name; return create_subvolume(mode, subvolume_folder)?0:1; } else if(cmd=="mountpoint") { if(argc<5) { std::cout << "Not enough parameters for mountpoint" << std::endl; return 1; } std::string clientname=handleFilename(argv[3]); std::string name=handleFilename(argv[4]); std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name; return get_mountpoint(mode, subvolume_folder)?0:1; } else if(cmd=="snapshot") { if(argc<6) { std::cout << "Not enough parameters for snapshot" << std::endl; return 1; } std::string clientname=handleFilename(argv[3]); std::string src_name=handleFilename(argv[4]); std::string dst_name=handleFilename(argv[5]); std::string subvolume_src_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+src_name; std::string subvolume_dst_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+dst_name; return create_snapshot(mode, subvolume_src_folder, subvolume_dst_folder)?0:1; } else if(cmd=="remove") { if(argc<5) { std::cout << "Not enough parameters for remove" << std::endl; return 1; } std::string clientname=handleFilename(argv[3]); std::string name=handleFilename(argv[4]); std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name; return remove_subvolume(mode, subvolume_folder)?0:1; } else if(cmd=="test") { std::cout << "Testing for btrfs..." << std::endl; std::string clientdir=backupfolder+os_file_sep()+"testA54hj5luZtlorr494"; bool create_dir_rc=os_create_dir(clientdir); if(!create_dir_rc) { remove_subvolume(mode_zfs, clientdir, true); remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"A", true); remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"B", true); os_remove_dir(clientdir); } create_dir_rc = create_dir_rc || os_create_dir(clientdir); if(create_dir_rc) { if(!create_subvolume(mode_btrfs, clientdir+os_file_sep()+"A") ) { std::cout << "TEST FAILED: Creating test btrfs subvolume failed" << std::endl; os_remove_dir(clientdir); return zfs_test(); } bool suc=true; if(!create_snapshot(mode_btrfs, clientdir+os_file_sep()+"A", clientdir+os_file_sep()+"B") ) { std::cout << "TEST FAILED: Creating test snapshot failed" << std::endl; suc=false; } if(suc) { writestring("test", clientdir+os_file_sep()+"A"+os_file_sep()+"test"); if(!os_create_hardlink(clientdir+os_file_sep()+"B"+os_file_sep()+"test", clientdir+os_file_sep()+"A"+os_file_sep()+"test", true, NULL)) { std::cout << "TEST FAILED: Creating cross sub-volume reflink failed. Need Linux kernel >= 3.6." << std::endl; suc=false; } else { if(getFile(clientdir+os_file_sep()+"B"+os_file_sep()+"test")!="test") { std::cout << "TEST FAILED: Cannot read reflinked file" << std::endl; suc=false; } } } if(!remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"A") ) { std::cout << "TEST FAILED: Removing subvolume A failed" << std::endl; suc=false; } if(!remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"B") ) { std::cout << "TEST FAILED: Removing subvolume B failed" << std::endl; suc=false; } if(!os_remove_dir(clientdir)) { std::cout << "TEST FAILED: Removing test clientdir failed" << std::endl; return 1; } if(!suc) { return 1; } } else { std::cout << "TEST FAILED: Creating test clientdir \"" << clientdir << "\" failed" << std::endl; return zfs_test(); } std::cout << "BTRFS TEST OK" << std::endl; return 10 + mode_btrfs; } else if(cmd=="issubvolume") { if(argc<5) { std::cout << "Not enough parameters for issubvolume" << std::endl; return 1; } std::string clientname=handleFilename(argv[3]); std::string name=handleFilename(argv[4]); std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name; return is_subvolume(mode, subvolume_folder)?0:1; } else if(cmd=="makereadonly") { if(argc<5) { std::cout << "Not enough parameters for makereadonly" << std::endl; return 1; } std::string clientname=handleFilename(argv[3]); std::string name=handleFilename(argv[4]); std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name; return make_readonly(mode, subvolume_folder)?0:1; } else { std::cout << "Command not found" << std::endl; return 1; } }
int main(int argc, char **argv) { // Record the start time of the program time_t start_time = time(NULL); int iters = 0; int k = 0; int elapsedTime; int rank, p; // Initialize MPI MPI_Init(&argc, &argv); MPI_Barrier(MPI_COMM_WORLD); elapsedTime = -MPI_Wtime(); // Get the rank of the curren process MPI_Comm_rank(MPI_COMM_WORLD, &rank); // Get the total number of processes MPI_Comm_size(MPI_COMM_WORLD, &p); //Number of inner loop iterations. Put loop around next[i,j]=(old[i-1,j...)*.25; int iters_per_cell = (argc > 1) ? atoi(argv[1]) : 1; //Number of iterations, same as before int iterations = (argc > 2) ? atoi(argv[2]) : 100; //How many ghost cell layers to send at a time & how many internal iterations to perform //per communication int boundary_thickness = (argc > 3) ? atoi(argv[3]) : 1; //Note: Ghost Cells are memory locations used to store redundant copies of //data held by neighboring processes // Extract the input parameters from the command line arguments // Number of columns in the grid (default = 1,000) int num_cols = 160; // Number of rows in the grid (default = 1,000) int total_num_rows = 160; // Number of iterations to simulate (default = 100) //int iterations = 100; int num_rows = (total_num_rows / p); // Output the simulation parameters //printf("Grid: %dx%d, Iterations: %d\n", num_cols, num_rows, iterations); // We allocate two arrays: one for the current time step and one for the next time step. // At the end of each iteration, we switch the arrays in order to avoid copying. // The arrays are allocated with an extra surrounding layer which contains // the immutable boundary conditions (this simplifies the logic in the inner loop). int added_boundary = 0; if (rank != 0) added_boundary+=boundary_thickness; if (rank != (p-1)) added_boundary+=boundary_thickness; num_rows += added_boundary; float **cells[2]; cells[0] = allocate_cells(num_cols + 2, num_rows + 2); cells[1] = allocate_cells(num_cols + 2, num_rows + 2); int cur_cells_index = 0, next_cells_index = 1; // Initialize the interior (non-boundary) cells to their initial value. // Note that we only need to initialize the array for the current time // step, since we will write to the array for the next time step // during the first iteration. initialize_cells(cells[0], num_cols, num_rows); // Set the immutable boundary conditions in both copies of the array int x, y, i; if (rank == 0) for (x = 1; x <= num_cols; x++) cells[0][0][x] = cells[1][0][x] = TOP_BOUNDARY_VALUE; if (rank == (p-1)) for (x = 1; x <= num_cols; x++) cells[0][num_rows + 1][x] = cells[1][num_rows + 1][x] = BOTTOM_BOUNDARY_VALUE; for (y = 1; y <= num_rows; y++) cells[0][y][0] = cells[1][y][0] = LEFT_BOUNDARY_VALUE; for (y = 1; y <= num_rows; y++) cells[0][y][num_cols + 1] = cells[1][y][num_cols + 1] = RIGHT_BOUNDARY_VALUE; MPI_Status status; int t = 0; // Simulate the heat flow for the specified number of iterations for (i = 0; i < iterations; i++) { // Traverse the plate, computing the new value of each cell if (t >= boundary_thickness) { int count = (boundary_thickness * num_cols); //Message passing if (rank != (p-1)) { //Pass lower real cells to rank+1's upper ghost cells //Recieve lower ghost cells from rank+1's upper real cells float lowerCells[boundary_thickness][num_cols]; int r, c = 0; for (r = 0; r < boundary_thickness; r++){ for (c = 0; c < num_cols; c++){ lowerCells[r][c] = cells[cur_cells_index][num_rows-boundary_thickness-1+r][c+1]; } } MPI_Send(&lowerCells, count, MPI_FLOAT, rank+1, 0, MPI_COMM_WORLD); MPI_Recv(&lowerCells, count, MPI_FLOAT, rank+1, 0, MPI_COMM_WORLD, &status); for (r = 0; r < boundary_thickness; r++){ for (c = 0; c < num_cols; c++){ cells[cur_cells_index][num_rows-boundary_thickness-1+r][c+1] = lowerCells[r][c]; } } } if (rank != 0) { //Recieve upper ghost cells from rank-1's lower real cells //Pass upper real cells to rank-1's lower ghost cells float upperCells[boundary_thickness][num_cols]; int r, c = 0; for (r = 0; r < boundary_thickness; r++){ for (c = 0; c < num_cols; c++){ upperCells[r][c] = cells[cur_cells_index][r+1][c+1]; } } MPI_Recv(&upperCells, count, MPI_FLOAT, rank-1, 0, MPI_COMM_WORLD, &status); MPI_Send(&upperCells, count, MPI_FLOAT, rank-1, 0, MPI_COMM_WORLD); for (r = 0; r < boundary_thickness; r++){ for (c = 0; c < num_cols; c++){ cells[cur_cells_index][r+1][c+1] = upperCells[r][c]; } } } t = 0; } for (y = 1; y <= num_rows; y++) { for (x = 1; x <= num_cols; x++) { int k = 0; for (k=0; k < iters_per_cell; k++){ // The new value of this cell is the average of the old values of this cell's four neighbors cells[next_cells_index][y][x] = (cells[cur_cells_index][y][x - 1] + cells[cur_cells_index][y][x + 1] + cells[cur_cells_index][y - 1][x] + cells[cur_cells_index][y + 1][x]) * 0.25; } } } // Swap the two arrays cur_cells_index = next_cells_index; next_cells_index = !cur_cells_index; t++; // Print the current progress //printf("Iteration: %d / %d\n", i + 1, iterations); } // Output a snapshot of the final state of the plate int final_cells = (iterations % 2 == 0) ? 0 : 1; //create_snapshot(cells[final_cells], num_cols, num_rows, iterations); // Compute and output the execution time time_t end_time = time(NULL); printf("\nExecution time: %d seconds\n", (int) difftime(end_time, start_time)); //End process prints out the full array if (rank == 0) { printf("\nRank 0 Gathering Cells\n"); float **allCells; allCells = allocate_cells(num_cols + 2, total_num_rows + 2); int i,j = 0; for (i = 0; i < (total_num_rows + 2); i++) { if (i < (num_rows - added_boundary + 2)) { for (j = 0; j < (num_cols + 2); j++) { allCells[i][j] = cells[final_cells][i][j]; } } else { int target; target = (i / (num_rows - added_boundary)); float **tempCells; int count = ((num_rows - boundary_thickness+2) * num_cols); printf("\nCount = %i", count); printf("\nRank 0 Wait On Rank %i\n", target); MPI_Recv(&tempCells, count, MPI_FLOAT, target, 0, MPI_COMM_WORLD, &status); int k; for (k = 0; k < count; k++) { for (j = 0; j < num_cols; j++) { allCells[i][j] = tempCells[k][j]; } } } } create_snapshot(allCells, num_cols, total_num_rows, iterations); } else { float **returnCells; returnCells = allocate_cells(num_cols, (num_rows - added_boundary)); int i,j = 0; for (i = 0; i < (num_rows - added_boundary); i++) { for (j = 0; j < num_cols; j++) { returnCells[i][j] = cells[final_cells][i+added_boundary][j]; } } int count = ((num_rows - added_boundary) * num_cols); printf("\nCount = %i", count); printf("\nRank %i Send To Rank 0\n", rank); MPI_Send(&returnCells, count, MPI_FLOAT, 0, 0, MPI_COMM_WORLD); } MPI_Barrier(MPI_COMM_WORLD); elapsedTime+=MPI_Wtime(); if (rank==0) { printf("\nElapsed time: %d seconds\n", (int) elapsedTime); } MPI_Finalize(); return 0; }
static void do_rangeupdate_test(uint32_t num_objs, uint32_t iters, uint32_t num_snaps) { struct ZS_thread_state *thd_state; int i = 0; uint32_t objs_updated = 0; ZS_status_t status; char *key; uint32_t keylen; char *act_value = NULL; uint64_t act_vallen; char *new_data = NULL; int error = 0; // uint32_t iter_print_cnt = 0; printf("============================= Snapshot RangeUpdate Test =========================\n"); fflush(stdout); ZSInitPerThreadState(zs_state, &thd_state); /* Test case 1: Let there be objects in snapshot, create new in active container and do rangeupdate on all keys, should be able to read updated data for all the keys and read old data for keys in snapshot */ open_stuff(thd_state, "cntr_3"); snapshot_cnt = 0; do_mput(thd_state, 0, (num_objs + (num_objs % 2))/2, 0, 0); create_snapshot(thd_state, i); do_mput(thd_state, (num_objs + (num_objs % 2))/2, (num_objs - (num_objs % 2))/2, 1, 0); ZSRangeUpdate(thd_state, cguid, "key_", strlen("key_"), range_update_cb, NULL, NULL, NULL, &objs_updated); printf("RangeUpdated objs_update: %d\n", objs_updated); if (objs_updated != num_objs) { printf("ERROR: All objects are not updated\n"); return; } key = malloc(ZS_MAX_KEY_LEN); for (i = 0; i < num_objs; i++) { sprintf(key, "key_%04d", i); keylen = strlen(key) + 1; act_value = NULL; status = ZSReadObject(thd_state, cguid, key, keylen, &act_value, &act_vallen); if (status != ZS_SUCCESS) { printf("ERROR: ZSRead returned status=%s, expected status=%s for " "key %d\n", ZSStrError(status), ZSStrError(ZS_SUCCESS), i); error++; fflush(stdout); free(key); break; } if (values[i].vallen + length_incr != act_vallen) { fprintf(stdout, "ERROR: Mismatch: Actual datalen=%u, " "Expected datalen=%u for key %u\n", (uint32_t)act_vallen, (uint32_t)values[i].vallen + length_incr, i); error++; fflush(stdout); free(act_value); free(key); break; } new_data = NULL; new_data = (char *) malloc(act_vallen); gen_data(new_data, act_vallen, 1000 + i); if (memcmp(new_data, act_value, act_vallen) != 0) { fprintf(stdout, "ERROR: Mismatch: Actual data differs " "with expected data for key %u\n", i); error++; fflush(stdout); break; } //free(key); //free(new_data); //free(act_value); } do_read_verify_snapshot(thd_state, 0, (num_objs + (num_objs % 2))/2, 0, 20); free_stuff(thd_state); /* Test case 2: Create a subtree having a key with its snapshot data, and rangeupdate on all keys, should be able to read updated data for key and data of the key of each snapshot */ status = ZS_SUCCESS; open_stuff(thd_state, "cntr_3"); do_mput(thd_state, 0, num_objs, 0, 0); create_snapshot(thd_state, 0); key = malloc(ZS_MAX_KEY_LEN); for (i = 0; i < num_snaps; i++) { sprintf(key, "key_%04d", num_objs/2); keylen = strlen(key) + 1; if (i%2 == 0) { act_vallen = OVERFLOW_DATA_SIZE; } else { act_vallen = INNODE_DATA_SIZE; } new_data = (char *) malloc(act_vallen); gen_data(new_data, act_vallen, 123 + i); status = ZSWriteObject(thd_state, cguid, key, keylen, new_data, act_vallen, 0); if (status != ZS_SUCCESS) { printf("WriteObject failed (%d) error: %s\n", i, ZSStrError(status)); break; } create_snapshot(thd_state, i + 1); free(new_data); } objs_processed = 0; ZSRangeUpdate(thd_state, cguid, "key_", strlen("key_"), range_update_cb, NULL, NULL, NULL, &objs_updated); if (objs_updated != num_objs) { printf("ERROR: All objects are not updated\n"); return; } for (i = 0; i < num_objs; i++) { key = malloc(ZS_MAX_KEY_LEN); sprintf(key, "key_%04d", i); keylen = strlen(key) + 1; act_value = NULL; status = ZSReadObject(thd_state, cguid, key, keylen, &act_value, &act_vallen); if (status != ZS_SUCCESS) { printf("ZSRead returned status=%s, expected status=%s for " "key %d\n", ZSStrError(status), ZSStrError(ZS_SUCCESS), i); error++; fflush(stdout); free(key); break; } if (values[i].vallen + length_incr != act_vallen) { fprintf(stdout, "ERROR: Mismatch: Actual datalen=%u, " "Expected datalen=%u for key %u\n", (uint32_t)act_vallen, (uint32_t)values[i].vallen + length_incr, i); error++; fflush(stdout); free(act_value); free(key); break; } new_data = NULL; new_data = (char *) malloc(act_vallen); gen_data(new_data, act_vallen, 1000 + i); if (memcmp(new_data, act_value, act_vallen) != 0) { fprintf(stdout, "ERROR: Mismatch: Actual data differs " "with expected data for key %u\n", i); error++; fflush(stdout); break; } free(key); free(new_data); free(act_value); } free_stuff(thd_state); ZSReleasePerThreadState(&thd_state); }
static void do_delete_test(uint32_t num_objs, uint32_t iters, uint32_t num_snaps) { struct ZS_thread_state *thd_state; int i; uint32_t iter_print_cnt = 0; printf("============================= Snapshot object Delete Test =========================\n"); fflush(stdout); ZSInitPerThreadState(zs_state, &thd_state); open_stuff(thd_state, "cntr_2"); snapshot_cnt = 0; /* Write the contents of snapshots */ for (i = 0; i < num_snaps; i++) { printf("Iter: %u: Mputting %u objects\n", ++iter_print_cnt, num_objs); fflush(stdout); do_mput(thd_state, 0, num_objs, i, 0); printf("Creating Snapshot %u\n", i); fflush(stdout); create_snapshot(thd_state, i); } #if 0 #include <string.h> printf("Waiting to get confirmation to proceed\n"); getchar(); #endif /* After delete, validate if the latest data is reported * not found and earlier snapshot still intact */ do_delete(thd_state, 0, num_objs, ZS_SUCCESS); do_read_verify(thd_state, 0, num_objs, ZS_OBJECT_UNKNOWN); do_read_verify_snapshot(thd_state, 0, num_objs, num_snaps-1, 20); /* Do a range query (read/verify active snapshot) and * ensure that no objects are found */ printf("Doing range query for latest update\n"); do_read_verify_snapshot(thd_state, 0, 0, num_snaps, 20); /* Do delete on top of tombstone delete and ensure it * says key not found */ do_delete(thd_state, 0, num_objs, ZS_OBJECT_UNKNOWN); for (i = 0; i < num_snaps; i++) { printf("Deleting Snapshot %u\n", i+1); fflush(stdout); delete_snapshot(thd_state, i); } /* Do another round of insert on top of tombstoned one and * delete them to see if we still see key not found */ printf("Iter: %u: Mputting %u objects\n", ++iter_print_cnt, num_objs); fflush(stdout); do_mput(thd_state, 0, num_objs, iters++, 0); do_delete(thd_state, 0, num_objs, ZS_SUCCESS); do_read_verify(thd_state, 0, num_objs, ZS_OBJECT_UNKNOWN); free_stuff(thd_state); ZSReleasePerThreadState(&thd_state); }
HRESULT __stdcall BtrfsContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { if (ignore) return E_INVALIDARG; if (!bg) { if ((IS_INTRESOURCE(pici->lpVerb) && pici->lpVerb == 0) || !strcmp(pici->lpVerb, SNAPSHOT_VERBA)) { UINT num_files, i; WCHAR fn[MAX_PATH]; if (!stgm_set) return E_FAIL; num_files = DragQueryFileW((HDROP)stgm.hGlobal, 0xFFFFFFFF, NULL, 0); if (num_files == 0) return E_FAIL; for (i = 0; i < num_files; i++) { if (DragQueryFileW((HDROP)stgm.hGlobal, i, fn, sizeof(fn) / sizeof(MAX_PATH))) { create_snapshot(pici->hwnd, fn); } } return S_OK; } return E_FAIL; } if ((IS_INTRESOURCE(pici->lpVerb) && pici->lpVerb == 0) || !strcmp(pici->lpVerb, NEW_SUBVOL_VERBA)) { HANDLE h; IO_STATUS_BLOCK iosb; NTSTATUS Status; ULONG pathlen, searchpathlen, pathend; WCHAR name[MAX_PATH], *searchpath; HANDLE fff; WIN32_FIND_DATAW wfd; if (!LoadStringW(module, IDS_NEW_SUBVOL_FILENAME, name, MAX_PATH)) { ShowError(pici->hwnd, GetLastError()); return E_FAIL; } h = CreateFileW(path, FILE_ADD_SUBDIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); if (h == INVALID_HANDLE_VALUE) { ShowError(pici->hwnd, GetLastError()); return E_FAIL; } pathlen = wcslen(path); searchpathlen = pathlen + wcslen(name) + 10; searchpath = (WCHAR*)malloc(searchpathlen * sizeof(WCHAR)); StringCchCopyW(searchpath, searchpathlen, path); StringCchCatW(searchpath, searchpathlen, L"\\"); pathend = wcslen(searchpath); StringCchCatW(searchpath, searchpathlen, name); fff = FindFirstFileW(searchpath, &wfd); if (fff != INVALID_HANDLE_VALUE) { ULONG i = wcslen(searchpath), num = 2; do { FindClose(fff); searchpath[i] = 0; if (StringCchPrintfW(searchpath, searchpathlen, L"%s (%u)", searchpath, num) == STRSAFE_E_INSUFFICIENT_BUFFER) { MessageBoxW(pici->hwnd, L"Filename too long.\n", L"Error", MB_ICONERROR); CloseHandle(h); return E_FAIL; } fff = FindFirstFileW(searchpath, &wfd); num++; } while (fff != INVALID_HANDLE_VALUE); } Status = NtFsControlFile(h, NULL, NULL, NULL, &iosb, FSCTL_BTRFS_CREATE_SUBVOL, NULL, 0, &searchpath[pathend], wcslen(&searchpath[pathend]) * sizeof(WCHAR)); free(searchpath); if (Status != STATUS_SUCCESS) { CloseHandle(h); ShowNtStatusError(pici->hwnd, Status); return E_FAIL; } CloseHandle(h); return S_OK; } return E_FAIL; }
static int do_create_snapshot(struct ploop_disk_images_data *di, const char *guid, const char *snap_dir, int temporary) { int ret; int fd; char dev[64]; char snap_guid[UUID_SIZE]; char file_guid[UUID_SIZE]; char fname[PATH_MAX]; char conf[PATH_MAX]; char conf_tmp[PATH_MAX]; int online = 0; int n; off_t size; __u32 blocksize; int version; if (guid != NULL && !is_valid_guid(guid)) { ploop_err(0, "Incorrect guid %s", guid); return SYSEXIT_PARAM; } if (is_old_snapshot_format(di)) return SYSEXIT_PARAM; ret = gen_uuid_pair(snap_guid, sizeof(snap_guid), file_guid, sizeof(file_guid)); if (ret) { ploop_err(errno, "Can't generate uuid"); return ret; } if (guid != NULL) { if (find_snapshot_by_guid(di, guid) != -1) { ploop_err(0, "The snapshot %s already exist", guid); return SYSEXIT_PARAM; } strcpy(snap_guid, guid); } n = get_snapshot_count(di); if (n == -1) { return SYSEXIT_PARAM; } else if (n > 128-2) { /* The number of images limited by 128 so the snapshot limit 128 - base_image - one_reserverd */ ploop_err(errno, "Unable to create a snapshot." " The maximum number of snapshots (%d) has been reached", n-1); return SYSEXIT_PARAM; } ret = ploop_find_dev_by_dd(di, dev, sizeof(dev)); if (ret == -1) return SYSEXIT_SYS; else if (ret == 0) { online = 1; ret = complete_running_operation(di, dev); if (ret) return ret; } else { ret = get_image_param_offline(di, di->top_guid, &size, &blocksize, &version); if (ret == SYSEXIT_OPEN && errno == EBUSY) { /* repair top delta */ char *topdelta[] = {find_image_by_guid(di, di->top_guid), NULL}; blocksize = di->blocksize; ret = check_deltas(di, topdelta, 0, &blocksize); if (ret) return ret; ret = get_image_param_offline(di, di->top_guid, &size, &blocksize, &version); } if (ret) return ret; } ret = merge_temporary_snapshots(di); if (ret) return ret; if (snap_dir != NULL) { char *name; char *dir; dir = realpath(snap_dir, NULL); if (dir == NULL) { ploop_err(errno, "Error in realpath(%s)", snap_dir); return SYSEXIT_CREAT; } name = strrchr(di->images[0]->file, '/'); if (name != NULL) name++; else name = di->images[0]->file; snprintf(fname, sizeof(fname), "%s/%s.%s", dir, name, file_guid); free(dir); } else snprintf(fname, sizeof(fname), "%s.%s", di->images[0]->file, file_guid); ploop_di_change_guid(di, di->top_guid, snap_guid); if (temporary) ploop_di_set_temporary(di, snap_guid); ret = ploop_di_add_image(di, fname, TOPDELTA_UUID, snap_guid); if (ret) return ret; get_disk_descriptor_fname(di, conf, sizeof(conf)); snprintf(conf_tmp, sizeof(conf_tmp), "%s.tmp", conf); ret = ploop_store_diskdescriptor(conf_tmp, di); if (ret) return ret; if (!online) { // offline snapshot fd = create_snapshot_delta(fname, blocksize, size, version); if (fd < 0) { ret = SYSEXIT_CREAT; goto err; } close(fd); } else { // Always sync fs ret = create_snapshot(dev, fname, 1); if (ret) goto err; } if (rename(conf_tmp, conf)) { ploop_err(errno, "Can't rename %s %s", conf_tmp, conf); ret = SYSEXIT_RENAME; } if (ret && !online && unlink(fname)) ploop_err(errno, "Can't unlink %s", fname); ploop_log(0, "ploop %s %s has been successfully created", get_snap_str(temporary), snap_guid); err: if (ret && unlink(conf_tmp)) ploop_err(errno, "Can't unlink %s", conf_tmp); return ret; }
int main(int argc, char **argv) { // Record the start time of the program time_t start_time = time(NULL); pthread_t *threads; threads=(pthread_t *)malloc(THREAD_COUNT*sizeof(*threads)); // Extract the input parameters from the command line arguments // Number of columns in the grid (default = 1,000) int num_cols = (argc > 1) ? atoi(argv[1]) : 1000; // Number of rows in the grid (default = 1,000) int num_rows = (argc > 2) ? atoi(argv[2]) : 1000; // Number of iterations to simulate (default = 100) int iterations = (argc > 3) ? atoi(argv[3]) : 100; int cur_cells_index = 0, next_cells_index = 1; // Output the simulation parameters printf("Grid: %dx%d, Iterations: %d\n", num_cols, num_rows, iterations); // We allocate two arrays: one for the current time step and one for the next time step. // At the end of each iteration, we switch the arrays in order to avoid copying. // The arrays are allocated with an extra surrounding layer which contains // the immutable boundary conditions (this simplifies the logic in the inner loop). float **cells[2]; int x, y, i, j; cells[0] = allocate_cells(num_cols + 2, num_rows + 2); cells[1] = allocate_cells(num_cols + 2, num_rows + 2); initialize_cells(cells[0], num_cols, num_rows); for (x = 1; x <= num_cols; x++) cells[0][0][x] = cells[1][0][x] = TOP_BOUNDARY_VALUE; for (x = 1; x <= num_cols; x++) cells[0][num_rows + 1][x] = cells[1][num_rows + 1][x] = BOTTOM_BOUNDARY_VALUE; for (y = 1; y <= num_rows; y++) cells[0][y][0] = cells[1][y][0] = LEFT_BOUNDARY_VALUE; for (y = 1; y <= num_rows; y++) cells[0][y][num_cols + 1] = cells[1][y][num_cols + 1] = RIGHT_BOUNDARY_VALUE; param p[THREAD_COUNT]; for (i=0; i < THREAD_COUNT; i++){ p[i].cells[0] = cells[0]; p[i].cells[1] = cells[1]; p[i].start_row = i * (num_rows/THREAD_COUNT) + 1; p[i].end_row = (i + 1) * (num_rows/THREAD_COUNT); p[i].num_rows = num_rows; p[i].num_cols = num_cols; } for (j = 0; j < iterations; j++) { printf("Iteration: %d / %d\n", j + 1, iterations); for (i=0; i < THREAD_COUNT; i++){ printf("%d, %d\n", p[i].start_row, p[i].end_row); p[i].cur_cells_index = cur_cells_index; p[i].next_cells_index = next_cells_index; pthread_create(&threads[i], NULL, iterate_plate_rows, (void *) &p[i]); printf("Creating thread %d\n", i); } for (i=0; i < THREAD_COUNT; i++){ pthread_join(threads[i], (void *)NULL); printf("Waiting for the thread %d\n", i); } // Swap the two arrays printf("Swapping in iteration %d\n", j+1); cur_cells_index = next_cells_index; next_cells_index = !cur_cells_index; } // Output a snapshot of the final state of the plate int final_cells = (iterations % 2 == 0) ? 0 : 1; create_snapshot(cells[final_cells], num_cols, num_rows, iterations); // Compute and output the execution time time_t end_time = time(NULL); printf("\nExecution time: %d seconds\n", (int) difftime(end_time, start_time)); return 0; }
int do_RETR(ftp_session *s, char *param) { int len; char arg[MAX_FTP_PATH], ftp_dir[MAX_FTP_PATH], buf[MAX_BUFFER]; FILE *fp; size_t read, write; SOCKET sockfd; #ifdef USE_SPECIAL_FILE int type, start, size; char *mem; #endif MATCH_SP(param); len = get_string(param, arg, sizeof(arg)); if (len == 0) return 501; param += len; MATCH_CRLF(param); if (!parse_dir(s->dir, arg, ftp_dir)) return 550; #ifndef USE_SPECIAL_FILE if (!ftp_to_fs_read(ftp_dir, arg)) return 550; #else type = get_special_file(ftp_dir); if (type == file_INVALID && !ftp_to_fs_read(ftp_dir, arg)) return 550; if (type != file_INVALID) { start = 0; switch (type) { #ifdef USE_SCREEN_BMP case file_SCREEN_BMP: mem = create_snapshot(&size); if (mem == NULL) return 450; break; #endif #ifdef USE_SCREEN_JPG case file_SCREEN_ZIP: { mem = create_jpeg(&size); if (mem == NULL) return 450; break; } #endif default: return 450; } } else #endif { fp = fopen(arg, "rb"); if (fp == NULL) return 450; } if (s->prev_command == cmd_REST) { #ifdef USE_SPECIAL_FILE if (type != file_INVALID) start = s->restart; else #endif fseek(fp, s->restart, SEEK_SET); } ftp_printf(s->control, reply_150); sockfd = ftp_connect(s); if (sockfd == -1) { #ifdef USE_SPECIAL_FILE if (type != file_INVALID) free(mem); else #endif fclose(fp); return 425; } #ifdef USE_SPECIAL_FILE if (type != file_INVALID) { write = my_send(sockfd, &mem[start], size-start, 0); free(mem); if (write != size-start) { closesocket(sockfd); return 426; } } else #endif { while (!feof(fp)) { s->tick = GetTickCount(); read = fread(buf, 1, sizeof(buf), fp); if (ferror(fp)) { closesocket(sockfd); fclose(fp); return 451; } write = my_send(sockfd, buf, read, 0); if (read != write) { closesocket(sockfd); fclose(fp); return 426; } } fclose(fp); } closesocket(sockfd); return 226; }