template<class ST> void CDenseFeatures<ST>::initialize_cache() { if (m_subset_stack->has_subsets()) SG_ERROR("A subset is set, cannot call initialize_cache\n"); if (num_features && num_vectors) { SG_UNREF(feature_cache); feature_cache = new CCache<ST>(get_cache_size(), num_features, num_vectors); SG_REF(feature_cache); } }
//// DO NOT CHANGE ANYTHING BELOW THIS POINT int main(void) { int size; int assoc; int block_size; int i; /* The cache needs to be initialized, but the parameters will be ignored by the mystery caches, as they are hard coded. You can test your geometry paramter discovery routines by calling cache_init() w/ your own size and block size values. */ cache_init(64*1024,16); flush_cache(); /* for (i = 0; i < 17; i++) { if (!access_cache(addr + i)) printf("%lld miss\n", addr + i); else printf("%lld hit\n", addr + i); } for (i = 0; i < 17; i++) { if (!access_cache(addr + i)) printf("%lld miss\n", addr + i); else printf("%lld hit\n", addr + i); } for (i = 17; i < 34; i++) { if (!access_cache(addr + i)) printf("%lld miss\n", addr + i); else printf("%lld hit\n", addr + i); } */ block_size=get_block_size(); size=get_cache_size(block_size); assoc=get_cache_assoc(size); printf("Cache block size: %d bytes\n", block_size); printf("Cache size: %d bytes\n", size); printf("Cache associativity: %d\n", assoc); return EXIT_SUCCESS; }
int main(void) { int size; int assoc; int block_size; cache_init(0,0); block_size=get_block_size(); size=get_cache_size(block_size); assoc=get_cache_assoc(size); printf("Cache block size: %d bytes\n", block_size); printf("Cache size: %d bytes\n", size); printf("Cache associativity: %d\n", assoc); return EXIT_SUCCESS; }
/* Returns the associativity of the cache. */ int get_cache_assoc() { flush_cache(); //int block_size = get_block_size(); int cache_size = get_cache_size(0); int block_size = get_block_size(); int addr = 0, replace_addr = 0; for (; addr < cache_size; addr += block_size){ access_cache(addr); } int special_addr = cache_size * 2 - block_size; // 11111... access_cache(special_addr); for(; replace_addr < cache_size && access_cache(replace_addr); replace_addr += block_size); return cache_size / (replace_addr + block_size); }
//// DO NOT CHANGE ANYTHING BELOW THIS POINT int main(void) { int size; int assoc; int block_size; /* The cache needs to be initialized, but the parameters will be ignored by the mystery caches, as they are hard coded. You can test your geometry paramter discovery routines by calling cache_init() w/ your own size and block size values. */ cache_init(1,1); block_size=get_block_size(); size=get_cache_size(block_size); assoc=get_cache_assoc(size); printf("Cache block size: %d bytes\n", block_size); printf("Cache size: %d bytes\n", size); printf("Cache associativity: %d\n", assoc); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int sflag = 0, s1flag = 0, s2flag = 0, nflag = 0, dflag = 0, eflag = 0; char *options, *value; extern char *optarg; extern int optind; int c, d; struct rlimit rl; int mode = RPC_SVC_MT_AUTO; int maxrecsz = RPC_MAXDATASIZE; void detachfromtty(void); int setmodulus(); int pk_nodefaultkeys(); int svc_create_local_service(); char domainname[MAXNETNAMELEN + 1]; /* * Set our allowed number of file descriptors to the max * of what the system will allow, limited by FD_SETSIZE. */ if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { rlim_t limit; if ((limit = rl.rlim_max) > FD_SETSIZE) limit = FD_SETSIZE; rl.rlim_cur = limit; (void) setrlimit(RLIMIT_NOFILE, &rl); (void) enable_extended_FILE_stdio(-1, -1); } __key_encryptsession_pk_LOCAL = &__key_encrypt_pk_2_svc; __key_decryptsession_pk_LOCAL = &__key_decrypt_pk_2_svc; __key_gendes_LOCAL = &__key_gen_1_svc; /* * Pre-option initialisation */ (void) umask(066); /* paranoia */ if (geteuid() != 0) { (void) fprintf(stderr, "%s must be run as root\n", argv[0]); exit(1); } setmodulus(HEXMODULUS); openlog("keyserv", LOG_PID, LOG_DAEMON); /* * keyserv will not work with a null domainname. */ if (getdomainname(domainname, MAXNETNAMELEN+1) || (domainname[0] == '\0')) { syslog(LOG_ERR, "could not get a valid domainname.\n"); exit(SMF_EXIT_ERR_CONFIG); } /* * Initialise security mechanisms */ cache_size = NULL; cache_options = NULL; if (init_mechs() == -1) { disk_caching = 0; } defaults(); while ((c = getopt(argc, argv, "ndDet:cs:")) != -1) switch (c) { case 'n': nflag++; break; case 'd': dflag++; use_nobody_keys = FALSE; break; case 'e': eflag++; use_nobody_keys = TRUE; break; case 'D': debugging = 1; break; case 't': nthreads = atoi(optarg); break; case 'c': disk_caching = 0; break; case 's': if (!disk_caching) { fprintf(stderr, "missing configuration file"); fprintf(stderr, " or -c option specified\n"); usage(); } sflag++; /* * Which version of [-s] do we have...? */ if (strchr((const char *) optarg, '=') == NULL) { /* * -s <size> */ if (s1flag) { fprintf(stderr, "duplicate" " [-s <size>]\n"); usage(); } s1flag++; default_cache = get_cache_size(optarg); break; } /* * -s <mechtype>=<size>[,...] */ s2flag++; options = optarg; while (*options != '\0') { d = getsubopt(&options, cache_options, &value); if (d == -1) { /* Ignore unknown mechtype */ continue; } if (value == NULL) { fprintf(stderr, "missing cache size for " "mechtype %s\n", cache_options[d]); usage(); } cache_size[d] = get_cache_size(value); } break; default: usage(); break; } if (dflag && eflag) { (void) fprintf(stderr, "specify only one of -d and -e\n"); usage(); } if (use_nobody_keys == FALSE) { pk_nodefaultkeys(); } if (optind != argc) { usage(); } if (!disk_caching && sflag) { fprintf(stderr, "missing configuration file"); fprintf(stderr, " or -c option specified\n"); usage(); } if (debugging) { if (disk_caching) { char **cpp = cache_options; int *ip = cache_size; (void) fprintf(stderr, "default disk cache size: "); if (default_cache < 0) { (void) fprintf(stderr, "%d entries\n", abs(default_cache)); } else { (void) fprintf(stderr, "%dMB\n", default_cache); } (void) fprintf(stderr, "supported mechanisms:\n"); (void) fprintf(stderr, "\talias\t\tdisk cache size\n"); (void) fprintf(stderr, "\t=====\t\t===============\n"); while (*cpp != NULL) { (void) fprintf(stderr, "\t%s\t\t", *cpp++); if (*ip < 0) { (void) fprintf(stderr, "%d entries\n", abs(*ip)); } else { (void) fprintf(stderr, "%dMB\n", *ip); } ip++; } } else { (void) fprintf(stderr, "common key disk caching disabled\n"); } } /* * Post-option initialisation */ if (disk_caching) { int i; for (i = 0; mechs[i]; i++) { if ((AUTH_DES_COMPAT_CHK(mechs[i])) || (mechs[i]->keylen < 0) || (mechs[i]->algtype < 0)) continue; create_cache_file(mechs[i]->keylen, mechs[i]->algtype, cache_size[i] ? cache_size[i] : default_cache); } } getrootkey(&masterkey, nflag); /* * Set MT mode */ if (nthreads > 0) { (void) rpc_control(RPC_SVC_MTMODE_SET, &mode); (void) rpc_control(RPC_SVC_THRMAX_SET, &nthreads); } /* * Enable non-blocking mode and maximum record size checks for * connection oriented transports. */ if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrecsz)) { syslog(LOG_INFO, "unable to set max RPC record size"); } if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS, "netpath", "keyserv") == 0) { syslog(LOG_ERR, "%s: unable to create service for version %d\n", argv[0], KEY_VERS); exit(1); } if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS2, "netpath", "keyserv") == 0) { syslog(LOG_ERR, "%s: unable to create service for version %d\n", argv[0], KEY_VERS2); exit(1); } if (svc_create_local_service(keyprogram, KEY_PROG, KEY_VERS3, "netpath", "keyserv") == 0) { syslog(LOG_ERR, "%s: unable to create service for version %d\n", argv[0], KEY_VERS3); exit(1); } if (!debugging) { detachfromtty(); } if (svc_create(keyprogram, KEY_PROG, KEY_VERS, "door") == 0) { syslog(LOG_ERR, "%s: unable to create service over doors for version %d\n", argv[0], KEY_VERS); exit(1); } if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, "door") == 0) { syslog(LOG_ERR, "%s: unable to create service over doors for version %d\n", argv[0], KEY_VERS2); exit(1); } if (svc_create(keyprogram, KEY_PROG, KEY_VERS3, "door") == 0) { syslog(LOG_ERR, "%s: unable to create service over doors for version %d\n", argv[0], KEY_VERS3); exit(1); } svc_run(); abort(); /* NOTREACHED */ return (0); }
main(int argc, char **argv) { int disk_fd, c; char *disk_devname, *ssd_devname, *cachedev; sector_t block_size = 0, cache_size = 0; sector_t disk_devsize; int write_around = 0; pname = argv[0]; while ((c = getopt(argc, argv, "fs:b:vr")) != -1) { switch (c) { case 's': cache_size = get_cache_size(optarg); break; case 'b': block_size = get_block_size(optarg); /* Block size should be a power of 2 */ break; case 'v': verbose = 1; break; case 'f': force = 1; break; case 'r': write_around = 1; break; case '?': usage(pname); } } if (optind == argc) usage(pname); if (block_size == 0) block_size = 8; /* 4KB default blocksize */ cachedev = argv[optind++]; if (optind == argc) usage(pname); ssd_devname = argv[optind++]; if (optind == argc) usage(pname); disk_devname = argv[optind]; disk_fd = open(disk_devname, O_RDONLY); if (disk_fd < 0) { fprintf(stderr, "%s: Failed to open %s\n", pname, disk_devname); exit(1); } if (ioctl(disk_fd, BLKGETSIZE, &disk_devsize) < 0) { fprintf(stderr, "%s: Cannot get disk size %s\n", pname, disk_devname); exit(1); } printf("cachedev %s, ssd_devname %s, disk_devname %s\n", cachedev, ssd_devname, disk_devname); printf("cache mode %s, block_size %lu, cache_size %lu\n", ((write_around) ? "WRITE_AROUND" : "WRITE_THRU"), block_size, cache_size); sprintf(dmsetup_cmd, "echo 0 %lu flashcache-wt %s %s %d %lu ", disk_devsize, disk_devname, ssd_devname, write_around, block_size); if (cache_size > 0) { char cache_size_str[4096]; sprintf(cache_size_str, "%lu ", cache_size); strcat(dmsetup_cmd, cache_size_str); } /* Go ahead and create the cache. * XXX - Should use the device mapper library for this. */ strcat(dmsetup_cmd, "| dmsetup create "); strcat(dmsetup_cmd, cachedev); strcat(dmsetup_cmd, "\n"); load_module(); if (verbose) fprintf(stderr, "Creating FlashCache_wt Volume : %s", dmsetup_cmd); system(dmsetup_cmd); }
static unsigned char * get_resource_info(struct terminal *term, void *data) { struct string info; long val; unsigned longlong bigval; if (!init_string(&info)) return NULL; #define val_add(text) \ add_format_to_string(&info, (const char *)text, val); add_to_string(&info, _("Resources", term)); add_to_string(&info, (const unsigned char *)": "); val = get_file_handles_count(); val_add(n_((unsigned char *)"%ld handle", (unsigned char *)"%ld handles", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_timers_count(); val_add(n_((unsigned char *)"%ld timer", (unsigned char *)"%ld timers", val, term)); add_to_string(&info, (const unsigned char *)".\n"); add_to_string(&info, _("Connections", term)); add_to_string(&info, (const unsigned char *)": "); val = get_connections_count(); val_add(n_((unsigned char *)"%ld connection", (unsigned char *)"%ld connections", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_connections_connecting_count(); val_add(n_((unsigned char *)"%ld connecting", (unsigned char *)"%ld connecting", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_connections_transfering_count(); val_add(n_((unsigned char *)"%ld transferring", (unsigned char *)"%ld transferring", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_keepalive_connections_count(); val_add(n_((unsigned char *)"%ld keepalive", (unsigned char *)"%ld keepalive", val, term)); add_to_string(&info, (const unsigned char *)".\n"); add_to_string(&info, _("Memory cache", term)); add_to_string(&info, (const unsigned char *)": "); /* What about just using Kibi/Mebi representation here? --jonas */ bigval = get_cache_size(); add_format_to_string(&info, (const char *)n_((unsigned char *)"%ld byte", (unsigned char *)"%ld bytes", bigval, term), bigval); add_to_string(&info, (const unsigned char *)", "); val = get_cache_entry_count(); val_add(n_((unsigned char *)"%ld file", (unsigned char *)"%ld files", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_cache_entry_used_count(); val_add(n_((unsigned char *)"%ld in use", (unsigned char *)"%ld in use", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_cache_entry_loading_count(); val_add(n_((unsigned char *)"%ld loading", (unsigned char *)"%ld loading", val, term)); add_to_string(&info, (const unsigned char *)".\n"); add_to_string(&info, _("Document cache", term)); add_to_string(&info, (const unsigned char *)": "); val = get_format_cache_size(); val_add(n_((unsigned char *)"%ld formatted", (unsigned char *)"%ld formatted", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_format_cache_used_count(); val_add(n_((unsigned char *)"%ld in use", (unsigned char *)"%ld in use", val, term)); add_to_string(&info, (const unsigned char *)", "); val = get_format_cache_refresh_count(); val_add(n_((unsigned char *)"%ld refreshing", (unsigned char *)"%ld refreshing", val, term)); add_to_string(&info, (const unsigned char *)".\n"); #ifdef CONFIG_ECMASCRIPT add_to_string(&info, _("ECMAScript", term)); add_to_string(&info, (const unsigned char *)": "); val = ecmascript_get_interpreter_count(); val_add(n_((unsigned char *)"%ld interpreter", (unsigned char *)"%ld interpreters", val, term)); add_to_string(&info, (const unsigned char *)".\n"); #endif add_to_string(&info, _("Interlinking", term)); add_to_string(&info, (const unsigned char *)": "); if (term->master) add_to_string(&info, _("master terminal", term)); else add_to_string(&info, _("slave terminal", term)); add_to_string(&info, (const unsigned char *)", "); val = list_size(&terminals); val_add(n_((unsigned char *)"%ld terminal", (unsigned char *)"%ld terminals", val, term)); add_to_string(&info, (const unsigned char *)", "); val = list_size(&sessions); val_add(n_((unsigned char *)"%ld session", (unsigned char *)"%ld sessions", val, term)); add_char_to_string(&info, '.'); #ifdef DEBUG_MEMLEAK add_char_to_string(&info, '\n'); add_to_string(&info, _("Memory allocated", term)); add_to_string(&info, (const unsigned char *)": "); val = mem_stats.amount; val_add(n_((unsigned char *)"%ld byte", (unsigned char *)"%ld bytes", val, term)); add_to_string(&info, ", "); val = mem_stats.true_amount - mem_stats.amount; val_add(n_((unsigned char *)"%ld byte overhead", (unsigned char *)"%ld bytes overhead", val, term)); add_format_to_string(&info, " (%0.2f%%).", (double) (mem_stats.true_amount - mem_stats.amount) / (double) mem_stats.amount * 100); #endif /* DEBUG_MEMLEAK */ #undef val_add return info.source; }
int main(int argc, char **argv) { int nvram_fd, cache_fd, disk_fd, c;//新增 nvram_fd char *disk_devname, *flash_devname, *nvram_devname, *cachedev;//新增 nvram_devname表示nvram缓存路径名字 struct flash_superblock *sb = (struct flash_superblock *)buf;//flash超级块的对象sb指向buf空间 struct flash_superblock *nsb = (struct flash_superblock *)nvram_buf;//新增 nb结构体 sector_t nvram_devsize, cache_devsize, disk_devsize;//新增 nvram_cache_devsize sector_t block_size = 0, md_block_size = 0, cache_size = 0, nvram_size = 0;//新增 nvram_size sector_t ram_needed;//typedef unsigned long sector_t; struct sysinfo i; int cache_sectorsize, nvram_sectorsize;//新增 nvram的扇区大小 int associativity = 512; int disk_associativity = 512; int ret; int cache_mode = -1; char *cache_mode_str; pname = argv[0]; //flashcache_create -p back flashcache /dev/pma /dev/pmb /dev/loop0 //flashcache_create [-v] -p back|around|thru [-s cache size] [-b block size] cachedevname flash_devname disk_devname while ((c = getopt(argc, argv, "fs:b:d:m:va:p:")) != -1) { switch (c) { case 's': //这个位置以后还可以初始化nvram_size属性 cache_size = get_cache_size(optarg);//s选项后面跟着的是缓存大小 默认大小,不然就要分别指定两个缓存的大小 break; case 'a': associativity = atoi(optarg);//缓存分组大小 break; case 'b': block_size = get_block_size(optarg);//缓存块大小 2的n次幂 /* Block size should be a power of 2 */ break; case 'd': disk_associativity = get_block_size(optarg);//磁盘分组大小 break; case 'm': md_block_size = get_block_size(optarg);//元数据块大小 /* MD block size should be a power of 2 */ break; case 'v': verbose = 1; break; case 'f': force = 1; break; case 'p': if (strcmp(optarg, "back") == 0) { //默认设置成WB模式 cache_mode = FLASHCACHE_WRITE_BACK; cache_mode_str = "WRITE_BACK"; } else if ((strcmp(optarg, "thru") == 0) || (strcmp(optarg, "through") == 0)) { cache_mode = FLASHCACHE_WRITE_THROUGH; cache_mode_str = "WRITE_THROUGH"; } else if (strcmp(optarg, "around") == 0) { cache_mode = FLASHCACHE_WRITE_AROUND; cache_mode_str = "WRITE_AROUND"; } else usage(pname); break; case '?': usage(pname); } } if (cache_mode == -1) usage(pname); if (optind == argc) usage(pname); if (block_size == 0) block_size = 8; /* 4KB default blocksize */ //缓存块大小默认为8个扇区,4KB if (md_block_size == 0) md_block_size = 8; /* 4KB default blocksize */ //元数据块大小也是一样 //进一步分别获取虚拟设备、flash设备和磁盘设备的名字 如果说参数个数提前用完了optind==argc,则调用usage返回错误信息 cachedev = argv[optind++]; if (optind == argc) usage(pname); //新增 获取nvram的设备路径名 nvram_devname = argv[optind++]; if (optind == argc) usage(pname); flash_devname = argv[optind++]; if (optind == argc) usage(pname); disk_devname = argv[optind]; //新增 对nvram路径名/磁盘分组大小的输出 //printf("cachedev %s, nvram_devname %s, flash_devname %s, disk_devname %s cache_mode %s disk_associativity %lu\n", // cachedev, nvram_devname, flash_devname, disk_devname, cache_mode_str, disk_associativity); if (cache_mode == FLASHCACHE_WRITE_BACK) printf("FLASHCACHE_WRITE_BACK:block_size %lu, md_block_size %lu, cache_size %lu\n", block_size, md_block_size, cache_size); else printf("block_size %lu, cache_size %lu\n", block_size, cache_size); //新增 读取nvram缓存空间的超级块中的数据,并判断nvram中是否已经有数据 nvram_fd = open(nvram_devname, O_RDONLY); if (nvram_fd < 0) { fprintf(stderr, "Failed to open %s\n", nvram_devname); exit(1); } lseek(nvram_fd, 0, SEEK_SET); if (read(nvram_fd, nvram_buf, 512) < 0) { fprintf(stderr, "Cannot read NVRAM superblock %s\n", nvram_devname); exit(1); } if (nsb->cache_sb_state == CACHE_MD_STATE_DIRTY || nsb->cache_sb_state == CACHE_MD_STATE_CLEAN || nsb->cache_sb_state == CACHE_MD_STATE_FASTCLEAN || nsb->cache_sb_state == CACHE_MD_STATE_UNSTABLE) { fprintf(stderr, "%s: Valid Flashcache already exists on %s\n", pname, nvram_devname); fprintf(stderr, "%s: Use flashcache_destroy first and then create again %s\n", pname, nvram_devname); exit(1); } //读取flash缓存空间的超级块中的数据 //指向文件的头部,并从头部开始读取512个字节的数据到buf中 那就应该是超级块只占用一个扇区大小? cache_fd = open(flash_devname, O_RDONLY); if (cache_fd < 0) { fprintf(stderr, "Failed to open %s\n", flash_devname); exit(1); } lseek(cache_fd, 0, SEEK_SET); if (read(cache_fd, buf, 512) < 0) { fprintf(stderr, "Cannot read Flash superblock %s\n", flash_devname); exit(1); } //通过flash缓存超级块的clean或者shutdown状态来判断是否已经有缓存数据在flash中 if (sb->cache_sb_state == CACHE_MD_STATE_DIRTY || sb->cache_sb_state == CACHE_MD_STATE_CLEAN || sb->cache_sb_state == CACHE_MD_STATE_FASTCLEAN || sb->cache_sb_state == CACHE_MD_STATE_UNSTABLE) { fprintf(stderr, "%s: Valid Flashcache already exists on %s\n", pname, flash_devname); fprintf(stderr, "%s: Use flashcache_destroy first and then create again %s\n", pname, flash_devname); exit(1); } // disk_fd = open(disk_devname, O_RDONLY); if (disk_fd < 0) { fprintf(stderr, "%s: Failed to open %s\n", pname, disk_devname); exit(1); } //新增 获取nvram设备空间大小BLKGETSIZE和物理扇区大小BLKSSZGET //并判断nvram缓存数据块大小是否大于nvram物理扇区大小和nvram缓存空间大小是否小于nvram设备大小 //不过默认cache_size应该为0,所以nvram_size也默认为0 if (ioctl(nvram_fd, BLKGETSIZE, &nvram_devsize) < 0) { fprintf(stderr, "%s: Cannot get nvram size %s\n", pname, nvram_devname); exit(1); } if (ioctl(nvram_fd, BLKSSZGET, &nvram_sectorsize) < 0) { fprintf(stderr, "%s: Cannot get nvram size %s\n", pname, nvram_devname); exit(1); } if (md_block_size > 0 && md_block_size * 512 < nvram_sectorsize) { fprintf(stderr, "%s: NVRAM device (%s) sector size (%d) cannot be larger than metadata block size (%d) !\n", pname, nvram_devname, nvram_sectorsize, md_block_size * 512); exit(1); } if (nvram_size && nvram_size > nvram_devsize) { fprintf(stderr, "%s: Cache size is larger than nvram size %lu/%lu\n", pname, nvram_size, nvram_devsize); exit(1); } //获取flash设备的空间大小并写入到cache_devsize中 if (ioctl(cache_fd, BLKGETSIZE, &cache_devsize) < 0) { fprintf(stderr, "%s: Cannot get cache size %s\n", pname, flash_devname); exit(1); } if (ioctl(disk_fd, BLKGETSIZE, &disk_devsize) < 0) { fprintf(stderr, "%s: Cannot get disk size %s\n", pname, disk_devname); exit(1); } //获取flash设备的物理扇区大小 if (ioctl(cache_fd, BLKSSZGET, &cache_sectorsize) < 0) { fprintf(stderr, "%s: Cannot get cache size %s\n", pname, flash_devname); exit(1); } //flash设备的物理扇区大小不能大于元数据块的大小 不然元数据块就成了管理flash的最小数据单元了 if (md_block_size > 0 && md_block_size * 512 < cache_sectorsize) { fprintf(stderr, "%s: SSD device (%s) sector size (%d) cannot be larger than metadata block size (%d) !\n", pname, flash_devname, cache_sectorsize, md_block_size * 512); exit(1); } //缓存空间大小不能大于flash设备空间大小 if (cache_size && cache_size > cache_devsize) { fprintf(stderr, "%s: Cache size is larger than ssd size %lu/%lu\n", pname, cache_size, cache_devsize); exit(1); } //新增 输出已获取到的设备信息 printf("flash:%s缓存大小为%d,设备大小为%d nvram:%s缓存大小为%d,设备大小为%d disk:%s设备大小为%d\n", flash_devname, cache_size, cache_devsize, nvram_devname, nvram_size, nvram_devsize, disk_devname, disk_devsize); /* Remind users how much core memory it will take - not always insignificant. * If it's > 25% of RAM, warn. */ //如果缓存空间大小没有在参数中赋值,为0,则为设备大小/块大小 *缓存块大小,即整个设备 //新增 nvram_size为0,ram_needed加上nvram设备大小 if (cache_size == 0 || nvram_size == 0) ram_needed = (cache_devsize / block_size) * sizeof(struct cacheblock) + (nvram_devsize / block_size) * sizeof(struct cacheblock); /* Whole device */ else ram_needed = (cache_size / block_size) * sizeof(struct cacheblock) + (nvram_size / block_size) * sizeof(struct cacheblock); sysinfo(&i); printf("Flashcache metadata will use %luMB of your %luMB main memory\n", ram_needed >> 20, i.totalram >> 20); //若是所使用的Flashcache元数据空间占内存空间比例超过1/4则提示 ram_needed不是整个缓存空间的大小吗?为什么说元数据? if (!force && ram_needed > (i.totalram * 25 / 100)) { fprintf(stderr, "Proportion of main memory needed for flashcache metadata is high.\n"); fprintf(stderr, "You can reduce this with a smaller cache or a larger blocksize.\n"); check_sure(); } //printf("输出一次disk_associativity=%lu associativity=%lu\n", disk_associativity, associativity); //磁盘分组大小不能大于缓存分组大小 if (disk_associativity == 0 || disk_associativity > associativity) { fprintf(stderr, "%s: Invalid Disk Associativity %ld\n", pname, disk_associativity); exit(1); } //printf("再输出一次disk_associativity=%lu associativity=%lu\n", disk_associativity, associativity); //缓存大小也不能大于磁盘大小 //新增 加入nvram_size > disk_devsize if (!force && (cache_size > disk_devsize || nvram_size > disk_devsize)) { fprintf(stderr, "Size of cache volume (%s) || (%s) is larger than disk volume (%s)\n", nvram_devname, flash_devname, disk_devname); check_sure(); } //新增 先提前输出一遍命令内容 共享cache_mode、block_size、assoc、md_block_size persistence默认为2,即create printf("echo 0 %lu flashcache disk=%s ssd=%s nvram=%s cachedev=%s cachemode=%d 2 blocksize=%lu cachesize=%lu nvramsize=%lu assoc=%d diskassoc=%d md_block_size=%lu" " | dmsetup create %s.\n", disk_devsize, disk_devname, flash_devname, nvram_devname, cachedev, cache_mode, block_size, cache_size, nvram_size, associativity, disk_associativity, md_block_size, cachedev); /* [root@localhost flashcache-3.1.3]# flashcache_create -p back cache1g8g /dev/pma /dev/pmb /dev/loop0 cachedev cache1g8g, nvram_devname /dev/pma, flash_devname /dev/pmb, disk_devname /dev/loop0 cache mode WRITE_BACK block_size 8, md_block_size 8, cache_size 0 Flashcache metadata will use 58MB of your 64426MB main memory echo 0 20971520 flashcache /dev/loop0 /dev/pmb /dev/pma cache1g8g 1 2 8 0 0 512 266287972864 8 | dmsetup create cache1g8g echo 0 20971520 flashcache /dev/loop0 /dev/pmb cachehaha 1 2 8 0 512 140733193388544 8 | dmsetup create cachehaha */ /* umount /dev/mapper/cachecache dmsetup remove cachecache rmmod flashcache flashcache_destroy /dev/pmb make && make install modprobe pmbd mode="pmbd1,8;hmo50;hms9;pmapY;rdsx1,2;wrsx1,12;" fdisk -l losetup /dev/loop0 /home/disk.img dd if=/dev/zero of=/root/workspace/disk.img bs=1024k count=131072 make KERNEL_TREE=/usr/src/kernels/2.6.32-504.12.2.el6.x86_64/ && make install modprobe flashcache lsmod | grep flashcache flashcache_create -p back cachecache /dev/pma /dev/pmb /dev/loop0 flashcache_create -p back cachecache /dev/pma /dev/loop0 mkfs.ext3 /dev/mapper/cachecache mount /dev/mapper/cachecache /home/mount fio -filename=/home/mount/file.1G -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=1G -numjobs=10 -runtime=1000 -group_reporting -name=mytest echo 0 20971520 flashcache disk=/dev/loop0 ssd=/dev/pmb nvram=/dev/pma cachedev=cachecache cachemode=1 2 blocksize=8 cachesize=0 nvramsize=0 assoc=512 diskassoc=512 md_block_size=8 | dmsetup create cachecache echo 0 20971520 flashcache /dev/loop0 /dev/pmb /dev/pma cachecache 1 2 8 0 0 512 512 8 | dmsetup create cachecache */ //设计创建设备的命令 先不加入nvram,不然后面需要加上解析参数的部分才能正常运行 sprintf(dmsetup_cmd, "echo 0 %lu flashcache %s %s %s %s %d 2 %lu %lu %lu %d %lu %lu" " | dmsetup create %s", disk_devsize, disk_devname, flash_devname, nvram_devname, cachedev, cache_mode, block_size, cache_size, nvram_size, associativity, disk_associativity, md_block_size, cachedev); printf("dmsetup_cmd:%s\n", dmsetup_cmd); /* Go ahead and create the cache. * XXX - Should use the device mapper library for this. */ load_module();//加载flashcache模块 if (verbose) fprintf(stderr, "Creating FlashCache Volume : \"%s\"\n", dmsetup_cmd); ret = system(dmsetup_cmd);//执行命令 创建设备 if (ret) { fprintf(stderr, "%s failed\n", dmsetup_cmd); exit(1); } return 0; }