int main(int argc, char *argv[]) { FILE *f; struct superblock sb; struct inode inode; if (argc < 3) { printf("Usage: %s <image file> <inode #>\n", argv[0]); return 1; } f = fopen(argv[1], "r"); if (f == NULL) { perror("fopen"); return 1; } if (get_superblock(f, &sb)) return 1; // Fetch the specified inode if (get_inode(&sb, strtoul(argv[2], NULL, 0), &inode)) return 1; // Print out some data about it print_inode(&inode); fclose(f); return 0; }
void print_inode_by_number(ext2_filesystem_t *fs, uint32_t inode, bool print_data, uint32_t data, bool list, bool blocks) { int rc; ext2_inode_ref_t *inode_ref; printf("Inode %u\n", inode); rc = ext2_filesystem_get_inode_ref(fs, inode, &inode_ref); if (rc != EOK) { printf(" Failed getting inode ref\n"); return; } print_inode(fs, inode_ref->inode, blocks); if (print_data) { print_inode_data(fs, inode_ref->inode, data); } if (list && ext2_inode_is_type(fs->superblock, inode_ref->inode, EXT2_INODE_MODE_DIRECTORY)) { print_directory_contents(fs, inode_ref); } rc = ext2_filesystem_put_inode_ref(inode_ref); if (rc != EOK) { printf(" Failed putting inode ref\n"); } }
int main(int argc, char *argv[]) { int fd; char *disk; if (argc > 1) disk = argv[1]; else disk = "mydisk"; if((fd = open(disk, O_RDONLY)) < 0) { perror("Open disk"); exit(1); } if(get_magic(fd) != 0xEF53) { printf("Not an ext2 file system\n"); exit(1); } putchar('\n'); print_inode(fd, ROOT_INODE); putchar('\n'); return 0; }
void print_root(){ debug("print_root:"); inode_t *rootp; rootp = retrieve_root(); print_inode(rootp); }
void tree(FS_t fs, bool verbose, bool root) { printf("\n\n"); // if (verbose) { // printf("\n========== FILE SYSTEM INFO ==========\n"); // printf("FILE SYSTEM SIZE: %d bytes\n", fs->fs_size); // printf("PAGE SIZE: %d bytes\n", fs->page_size); // printf("METADATA SIZE: %d bytes\n", fs->header_size); // printf("NUMBER OF INODES: %d\n", fs->num_inodes); // } if (root) { print_inode(fs->root, verbose, 0); } else { print_inode(fs->cd, verbose, 0); } printf("\n\n"); return; }
void testsVblocks(){ initTestIndx(); dump_superblock(); printf("print_inode(2) : %d\n", print_inode(1)); unsigned int testBlock = vblock_of_fblock(1, 100, false); printf("vblock_of_fblock(1, 100) = %u\n", testBlock); printf("Volume %s plein\n", (isVolFull() == 0) ? "NON ":""); printf("Espace restant : %d/%d (1 bloc reserve au superbloc)\n", volFreeSpace(), MBR.volumes[currentVol].size); disp_freelist(); }
main(int argc, char **argv) { struct ux_inode inode; char buf[512]; char command[512]; off_t nsectors; int error, i, blk; ino_t inum; devfd = open(argv[1], O_RDWR); if (devfd < 0) { fprintf(stderr, "uxmkfs: Failed to open device\n"); exit(1); } /* * Read in and validate the superblock */ read(devfd, (char *)&sb, sizeof(struct ux_superblock)); if (sb.s_magic != UX_MAGIC) { printf("This is not a uxfs filesystem\n"); exit(1); } while (1) { printf("uxfsdb > ") ; fflush(stdout); scanf("%s", command); if (command[0] == 'q') { exit(0); } if (command[0] == 'i') { inum = atoi(&command[1]); read_inode(inum, &inode); print_inode(inum, &inode); } if (command[0] == 's') { printf("\nSuperblock contents:\n"); printf(" s_magic = 0x%x\n", sb.s_magic); printf(" s_mod = %s\n", (sb.s_mod == UX_FSCLEAN) ? "UX_FSCLEAN" : "UX_FSDIRTY"); printf(" s_nifree = %d\n", sb.s_nifree); printf(" s_nbfree = %d\n\n", sb.s_nbfree); } } }
void gfs_init_inode(struct inode *inode, struct dentry *parent, u16 mode ) { struct gfs_inode_info *gfs_i = GFS_INODE(inode); inode_init_owner(inode, parent->d_inode, mode); inode->i_blocks = 1; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; inode->i_mode = mode; inode->i_size = 0; gfs_set_inode(inode); gfs_i->i_exino = 0xf8f8; print_inode(gfs_i); }
void print_inode(Inode_t *node, bool verbose, int lvl) { for (int i=0; i<lvl; i++) { printf("| "); } printf("+ "); printf("%s\n", node->name); if (verbose) { for (int i=0; i<lvl; i++) { printf("| "); } printf("| "); printf("%s\n", (node->itype == F) ? "File" : "Dir"); for (int i=0; i<lvl; i++) { printf("| "); } printf("| "); printf("%d\n", node->tag); for (int i=0; i<lvl; i++) { printf("| "); } printf("| "); printf("Size: %d\n", node->size); for (int i=0; i<lvl; i++) { printf("| "); } printf("| "); printf("\n"); } for (int j=2; j<node->size+2 && node->itype != F; j++) { print_inode(node->children[j], verbose, lvl+1); } return; }
static struct gfs_inode_info *gfs_iget_info(struct super_block *sb, u32 ino) { struct gfs_inode_info *gfs_inode; struct gfs_inode *raw_inode; struct buffer_head *bh; struct inode *vfs_inode; PDEBUG("ino=%d\n", (int)ino); vfs_inode = iget_locked(sb, ino); if(!vfs_inode) return ERR_PTR(-ENOMEM); gfs_inode = GFS_INODE(vfs_inode); if(vfs_inode->i_state & I_NEW) { bh = get_inode_data(gfs_inode, 0); if(!bh) { PDEBUG("IO\n"); return ERR_PTR(-EIO); } raw_inode = (struct gfs_inode*)bh->b_data; PDEBUG("Raw Inode %o\n", raw_inode->i_mode); gfs_init_inode_from_raw(gfs_inode, RAW_INODE(gfs_inode)); gfs_inode->i_ex_inode = NULL; gfs_inode->i_exino = 0xabcd; put_inode_data(gfs_inode, 0); unlock_new_inode(vfs_inode); } print_inode(gfs_inode); return gfs_inode; }
inode* build_inode(superblock* superBlock, FILE* diskImage, unsigned long offset, bool verbose) { int inodeOffset, i; inode* inodeList; inodeList = malloc(sizeof(inode) * superBlock->s_ninodes); inodeOffset = (2 + superBlock->s_imap_blocks + superBlock->s_zmap_blocks) * superBlock->s_block_size; fseek(diskImage, inodeOffset + offset, SEEK_SET); fread(inodeList, sizeof(inode) * superBlock->s_ninodes, superBlock->s_ninodes, diskImage); if (verbose) { /* for (i = 0; i < superBlock->s_ninodes; i++) { print_inode(inodeList+i); } */ /* Nevermind, just print the root inode. */ print_inode(inodeList); } return inodeList; }
int Server_SymLink(int inode_num,char *oldname,char *newname) { int i,blk_num; int last_slash=-1; int num; int res; int resF; int len=strlen(newname); char dir_path[MAXPATHNAMELEN+1]; struct inode curr_inode; char block[BLOCKSIZE]; if(inode_num<1||inode_num>max_inode_num||newname==NULL) return ERROR; for(i=0;i<len;i++) if(newname[i]=='/') last_slash=i; printf("\nReached in SymLink 1"); if(last_slash==0) res=ROOTINODE; else res=inode_num; if(last_slash>0) { printf("\nSymLink: Reached in Link_file 2"); strncpy(dir_path,newname,last_slash); dir_path[last_slash]='\0'; res=LookUp(dir_path,inode_num,0); if((res==ERROR)||(res==0)) { printf("\nERROR: Path %s does not exist ",dir_path); free(dir_path); return ERROR; } } strncpy(dir_path,&newname[last_slash+1],len-last_slash-1); dir_path[len-last_slash-1]='\0'; printf("\nSymLink : Value of dir_path is %s",dir_path); resF=LookUp(dir_path,res,0); printf("\nSymLink :Reached in Link_file 4 with resF as %d",resF); if(resF==ERROR) { printf("\nSymLink ERROR: Path %s does not exist ",dir_path); return ERROR; } if(resF!=0) { printf("\nSymLink ERROR: Pathname %s already exists ",newname); return ERROR; } resF=Get_free_inode(); if(resF==0) return ERROR; //GetInode(resF,&curr_inode); curr_inode.type=INODE_SYMLINK; curr_inode.nlink=1; curr_inode.size=strlen(oldname); blk_num=Get_free_blknum(); if(blk_num==0) { printf("\nSymLink ERROR: Not enough memory available!"); Add_free_inode(resF); return ERROR; } curr_inode.direct[0]=blk_num; GetBlock(blk_num,&block); strncpy(&block,oldname,strlen(oldname)+1); WriteBlock(blk_num,&block); PutInDir(res,resF,dir_path); write_inode(resF,&curr_inode); curr_inode.size=0; GetInode(resF,&curr_inode); print_inode(resF,&curr_inode); printf("\nReturning from SymLink"); return 0; }
static int lab4fs_fill_super(struct super_block * sb, void * data, int silent) { struct buffer_head * bh; int blocksize = BLOCK_SIZE; unsigned long logic_sb_block; unsigned offset = 0; unsigned long sb_block = 1; struct lab4fs_super_block *es; struct lab4fs_sb_info *sbi; struct inode *root; int hblock; int err = 0; sbi = kmalloc(sizeof(*sbi), GFP_KERNEL); if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; memset(sbi, 0, sizeof(*sbi)); blocksize = sb_min_blocksize(sb, BLOCK_SIZE); if (!blocksize) { LAB4ERROR("unable to set blocksize\n"); err = -EIO; goto out_fail; } /* * If the superblock doesn't start on a hardware sector boundary, * calculate the offset. */ if (blocksize != BLOCK_SIZE) { logic_sb_block = (sb_block * BLOCK_SIZE) / blocksize; offset = (sb_block * BLOCK_SIZE) % blocksize; } else { logic_sb_block = sb_block; } if (!(bh = sb_bread(sb, logic_sb_block))) { LAB4ERROR("unable to read super block\n"); goto out_fail; } es = (struct lab4fs_super_block *) (((char *)bh->b_data) + offset); sb->s_magic = le32_to_cpu(es->s_magic); if (sb->s_magic != LAB4FS_SUPER_MAGIC) { if (!silent) LAB4ERROR("VFS: Can't find lab4fs filesystem on dev %s.\n", sb->s_id); goto failed_mount; } sbi->s_sb = es; blocksize = le32_to_cpu(es->s_block_size); hblock = bdev_hardsect_size(sb->s_bdev); if (sb->s_blocksize != blocksize) { /* * Make sure the blocksize for the filesystem is larger * than the hardware sectorsize for the machine. */ if (blocksize < hblock) { LAB4ERROR("blocksize %d too small for " "device blocksize %d.\n", blocksize, hblock); goto failed_mount; } brelse (bh); sb_set_blocksize(sb, blocksize); logic_sb_block = (sb_block * BLOCK_SIZE) / blocksize; offset = (sb_block * BLOCK_SIZE) % blocksize; bh = sb_bread(sb, logic_sb_block); if (!bh) { LAB4ERROR("Can't read superblock on 2nd try.\n"); goto failed_mount; } es = (struct lab4fs_super_block *)(((char *)bh->b_data) + offset); sbi->s_sb = es; if (es->s_magic != cpu_to_le32(LAB4FS_SUPER_MAGIC)) { LAB4ERROR("Magic mismatch, very weird !\n"); goto failed_mount; } } sb->s_maxbytes = lab4fs_max_size(es); sbi->s_sbh = bh; sbi->s_log_block_size = log2(sb->s_blocksize); sbi->s_first_ino = le32_to_cpu(es->s_first_inode); sbi->s_inode_size = le32_to_cpu(es->s_inode_size); sbi->s_log_inode_size = log2(sbi->s_inode_size); sbi->s_inode_table = le32_to_cpu(es->s_inode_table); sbi->s_data_blocks = le32_to_cpu(es->s_data_blocks); sbi->s_next_generation = 0; sbi->s_free_inodes_count = le32_to_cpu(es->s_free_inodes_count); sbi->s_free_data_blocks_count = le32_to_cpu(es->s_free_data_blocks_count); sbi->s_inodes_count = le32_to_cpu(es->s_inodes_count); sbi->s_blocks_count = le32_to_cpu(es->s_blocks_count); sbi->s_inode_bitmap.nr_valid_bits = le32_to_cpu(es->s_inodes_count); sbi->s_data_bitmap.nr_valid_bits = le32_to_cpu(es->s_blocks_count) - le32_to_cpu(es->s_data_blocks); rwlock_init(&sbi->rwlock); sb->s_op = &lab4fs_super_ops; err = bitmap_setup(&sbi->s_inode_bitmap, sb, le32_to_cpu(es->s_inode_bitmap)); if (err) goto out_fail; err = bitmap_setup(&sbi->s_data_bitmap, sb, le32_to_cpu(es->s_data_bitmap)); if (err) goto out_fail; sbi->s_root_inode = le32_to_cpu(es->s_root_inode); root = iget(sb, sbi->s_root_inode); LAB4DEBUG("I can get the root inode\n"); print_inode(root); LAB4DEBUG("END\n"); sb->s_root = d_alloc_root(root); if (!sb->s_root) { iput(root); kfree(sbi); return -ENOMEM; } return 0; failed_mount: out_fail: kfree(sbi); return err; }
int Server_Write(int inode,int len,int offset,char *buff) { int size,blk_num,sec_num,i,k,j; int len_write=0,res; int total_blk,num_blk; int blk_offset; char str[BLOCKSIZE]; struct inode curr_inode; int final_size,final_total_blk; printf("\nWrite:Reached 1"); if(inode<1||inode>max_inode_num||buff==NULL) return ERROR; printf("\nWrite:Reached 1 with inode=%d",inode); res=GetInode(inode,&curr_inode); if(res==ERROR) return ERROR; printf("\nWrite :Reached 2 with inode type as %d",curr_inode.type); if(curr_inode.type!=INODE_REGULAR) return ERROR; printf("\nWrite :Reached 3"); size=curr_inode.size; printf("\nWrite :Reached 3"); if(offset>size+1) return ERROR; print_inode(inode,&curr_inode); printf("\nWrite :Reached 4 size=%d",size); total_blk=(size+BLOCKSIZE-1)/BLOCKSIZE; final_size=size+len; final_total_blk=(final_size+BLOCKSIZE-1)/BLOCKSIZE; printf("\nWrite :Reached 5 final block =%d and total blk =%d",final_total_blk,total_blk); /*res=Has_N_Free_Blocks(final_total_blk-total_blk); if(res==0) return ERROR;*/ for(i=total_blk;i<final_total_blk;i++) { blk_num=Get_free_blknum(); if(i<NUM_DIRECT) curr_inode.direct[i]=blk_num; else PutIndirectBlk(curr_inode.indirect,i-NUM_DIRECT,blk_num); } printf("\nWrite :Reached 5 "); num_blk=offset/BLOCKSIZE; for(k=num_blk;k<final_total_blk;k++) { if(k<NUM_DIRECT) blk_num=curr_inode.direct[k]; else blk_num=GetIndirectBlk(curr_inode.indirect,k-NUM_DIRECT); if(k==num_blk) { blk_offset=offset%BLOCKSIZE; res=GetBlock(blk_num,&str); if(res==ERROR) return ERROR; } else blk_offset=0; for(i=blk_offset;i<BLOCKSIZE/sizeof(char);i++) if(len_write<len) { str[i]=buff[len_write++]; curr_inode.size++; printf("\nCopied %c",buff[len_write-1]); } else { WriteBlock(blk_num,&str); write_inode(inode,&curr_inode); printf("\nReturning from Write()"); return len_write; } WriteBlock(blk_num,&str); } write_inode(inode,&curr_inode); return len_write; }
int ext2(void) { printf("Hello World, this is the Ext2 FS\n"); // Hardcode test fs into memory so that we can test read // Set up the superblock struct ext2_super_block *sb; sb = (struct ext2_super_block*) (VIRT_MEM_LOCATION + EXT2_SUPERBLOCK_LOCATION); sb->s_inodes_count = 50; sb->s_blocks_count = 8192; sb->s_r_blocks_count = 6; sb->s_free_blocks_count = 8186; sb->s_free_inodes_count = 49; sb->s_first_data_block = 1; sb->s_log_block_size = 0; sb->s_log_frag_size = 0; sb->s_blocks_per_group = 8192; sb->s_frags_per_group = 8192; sb->s_inodes_per_group = 50; sb->s_magic = EXT2_MAGIC; sb->s_state = EXT2_VALID_FS; sb->s_errors = EXT2_ERRORS_CONTINUE; sb->s_creator_os = EXT2_OS_XINU; sb->s_first_ino = 2; sb->s_inode_size = sizeof( struct ext2_inode ); sb->s_block_group_nr = 0; char name[16] = "FAKE RAM FS :D"; memcpy(sb->s_volume_name,name,16); // Set up the group descriptors table struct ext2_group_desc *gpd; // DUMB POINTER ARITHMATIC gpd = (struct ext2_group_desc *) (sb + 1); gpd->bg_block_bitmap = 2; gpd->bg_inode_bitmap = 3; gpd->bg_inode_table = 4; gpd->bg_free_blocks_count = 44; gpd->bg_free_inodes_count = 19; gpd->bg_used_dirs_count = 1; // Set up the block bitmap uint8 *blBitmap; blBitmap = (uint8 *) (sb + 2); blBitmap[0] = 0x3F; // super block int i; for (i = 6; i < sb->s_blocks_count; i++) blBitmap[i] = 0; // Set up the inode bitmap uint8 *iBitmap; iBitmap = (uint8 *) (sb + 3); iBitmap[0] = 0x1; // . for (i = 1; i < sb->s_inodes_count; i++) iBitmap[i] = 0; // Set up the inode table struct ext2_inode *iTbl; iTbl = (struct ext2_inode *) (sb + 4); // Set up . inode iTbl->i_mode = EXT2_S_IFDIR; iTbl->i_size = sizeof(struct ext2_dir_entry_2); iTbl->i_links_count = 0; iTbl->i_blocks = 1; iTbl->i_flags = EXT2_NODUMP_FL; iTbl->i_block[0] = 5; // Set up . entry for the home directory struct ext2_dir_entry_2 *blk5; blk5 = (struct ext2_dir_entry_2 *) (sb + 5); blk5->inode = 1; blk5->next_dirent = 0; blk5->name_len = 1; blk5->filetype = 2; char homeName[255] = "."; memcpy(blk5->name, homeName, 255); _fs_ext2_init(); touch1( xinu_fs, "./", "test" ); char bufferL[9] = "Go long!"; uint32 bytes_written; ext2_write_status stat = ext2_write_file_by_path( xinu_fs, "./test", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "yo"); stat = ext2_write_file_by_path( xinu_fs, "./yo", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "whoah" ); stat = ext2_write_file_by_path( xinu_fs, "./whoah", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "iasjdf" ); stat = ext2_write_file_by_path( xinu_fs, "./iasjdf", bufferL, &bytes_written, 0, 8 ); touch1( xinu_fs, "./", "f" ); stat = ext2_write_file_by_path( xinu_fs, "./f", bufferL, &bytes_written, 0, 8 ); ls1( xinu_fs, "./" ); printf("removing yo\n"); rm1( xinu_fs, "./", "yo" ); ls1( xinu_fs, "./" ); printf("touching asdf\n"); touch1( xinu_fs, "./", "asdf" ); stat = ext2_write_file_by_path( xinu_fs, "./asdf", bufferL, &bytes_written, 0, 8 ); ls1( xinu_fs, "./" ); printf("mking dir\n"); mkdir1( xinu_fs, "./", "dir" ); ls1( xinu_fs, "./" ); printf("touching yo\n"); touch1( xinu_fs, "./dir/", "yo" ); ls1( xinu_fs, "./dir/"); copy1( xinu_fs, "./", "whoah", "./", "hello" ); ls1( xinu_fs, "./" ); cat1( xinu_fs, "./", "hello" ); copy1( xinu_fs, "./", "hello", "./dir/", "hello" ); printf("HERE\n"); ls1( xinu_fs, "./dir/" ); cat1( xinu_fs, "./dir/", "hello" ); printf("removeing\n"); mv1( xinu_fs, "./dir/", "yo", "./", "a" ); ls1( xinu_fs, "./" ); cat1( xinu_fs, "./", "a" ); #if 0 // Test the read/write functions printf("Testing hardcoded data\n"); print_superblock( xinu_fs->sb ); struct ext2_inode *i1 = ext2_get_inode(xinu_fs, 1); print_inode( i1, 1, xinu_fs ); struct ext2_dir_entry_2 *home = ext2_get_first_dirent(xinu_fs, i1 ); print_dirent( home ); uint32 inode_num = ext2_inode_alloc( xinu_fs ); struct ext2_inode *i2 = ext2_get_inode( xinu_fs, inode_num+1 ); i2->i_mode = EXT2_S_IFREG; i2->i_size = 0; printf("Allocated new inode\n"); print_inode( i2, inode_num+1, xinu_fs ); struct ext2_dir_entry_2 *dirent = ext2_dirent_alloc( xinu_fs, i1 ); dirent->inode = 2; dirent->next_dirent = 0; dirent->name_len = 4; dirent->filetype = EXT2_FT_REG_FILE; char testName[255] = "test"; memcpy(dirent->name, testName, 255); printf("Allocated new dir_entry_2 test\n"); print_dirent( dirent ); char path[8] = "./test"; char buffer[14] = "Writing! Yay!"; char bufferL[9] = "Go long!"; uint32 bytes_written; ext2_write_status stat = ext2_write_file_by_path( xinu_fs, path, buffer, &bytes_written, 0, 13 ); printf("bytes_written = %d stat = %d\n", bytes_written, stat); char buffer2[12*1024]; // stat = ext2_write_file_by_path( xinu_fs, path, buffer2, // &bytes_written, 13, (12*1024)-1 ); printf("bytes_written = %d stat = %d\n", bytes_written, stat); // stat = ext2_write_file_by_path( xinu_fs, path, bufferL, // &bytes_written, (12*1024)+12, 8 ); printf("bytes_written = %d stat = %d\n", bytes_written, stat); int read = 0; char readBuf[30]; read = ext2_read_dirent( xinu_fs, dirent, readBuf, 0, 29); printf("Read %d bytes readBuf = %s\n", read, readBuf); // read = ext2_read_dirent( xinu_fs, dirent, readBuf, (12*1024)+12, 10); // printf("Read %d bytes readBuf = %s\n", read, readBuf); #endif return 0; }
int Server_Read(int inode,int len,int offset,char *buff) { int size,blk_num,sec_num,i,k,j; int len_read=0,res; int total_blk,num_blk; int blk_offset; char str[BLOCKSIZE]; struct inode curr_inode; printf("\nRead :Reached 0"); if(inode<1||inode>max_inode_num) { printf("\nERROR: Invalid Inode Number %d",inode); return ERROR; } printf("\nRead :Reached 1"); res=GetInode(inode,&curr_inode); if(res==ERROR) return ERROR; printf("\nRead :Reached 2"); if((curr_inode.type!=INODE_REGULAR)&&(curr_inode.type!=INODE_DIRECTORY)) return ERROR; printf("\nRead :Reached 3"); size=curr_inode.size; print_inode(inode,&curr_inode); if(offset>size) { printf("\noffset is more than file size"); return ERROR; } printf("\nRead :Reached 4 size=%d",size); num_blk=offset/BLOCKSIZE; total_blk=(size+BLOCKSIZE-1)/BLOCKSIZE; printf("\nRead :Reached 5 "); for(k=num_blk;k<total_blk;k++) { if(k<NUM_DIRECT) blk_num=curr_inode.direct[k]; else blk_num=GetIndirectBlk(curr_inode.indirect,k-NUM_DIRECT); res=GetBlock(blk_num,&str); if(res==ERROR) return ERROR; if(k==num_blk) blk_offset=offset%BLOCKSIZE; else blk_offset=0; for(i=blk_offset;i<BLOCKSIZE/sizeof(char);i++) if((len_read<len)&&(len_read+offset<size)) { buff[len_read++]=str[i]; printf("\nCopied %x",buff[len_read-1]); } else { buff[len_read]='\0'; printf("\nReturning from Read()with buff=%s\n",buff); return len_read; } } return len_read; }
int main(int ac, char **av) { const char *sel_path = NULL; const char *uuid_str = NULL; const char *arg; int pfs_type = HAMMER2_PFSTYPE_NONE; int all_opt = 0; int ecode = 0; int ch; srandomdev(); signal(SIGPIPE, SIG_IGN); dmsg_crypto_setup(); /* * Core options */ while ((ch = getopt(ac, av, "adfrqs:t:u:v")) != -1) { switch(ch) { case 'a': all_opt = 1; break; case 'd': DebugOpt = 1; break; case 'f': ForceOpt = 1; break; case 'r': RecurseOpt = 1; break; case 's': sel_path = optarg; break; case 't': /* * set node type for mkpfs */ if (strcasecmp(optarg, "ADMIN") == 0) { pfs_type = HAMMER2_PFSTYPE_ADMIN; } else if (strcasecmp(optarg, "CACHE") == 0) { pfs_type = HAMMER2_PFSTYPE_CACHE; } else if (strcasecmp(optarg, "COPY") == 0) { pfs_type = HAMMER2_PFSTYPE_COPY; } else if (strcasecmp(optarg, "SLAVE") == 0) { pfs_type = HAMMER2_PFSTYPE_SLAVE; } else if (strcasecmp(optarg, "SOFT_SLAVE") == 0) { pfs_type = HAMMER2_PFSTYPE_SOFT_SLAVE; } else if (strcasecmp(optarg, "SOFT_MASTER") == 0) { pfs_type = HAMMER2_PFSTYPE_SOFT_MASTER; } else if (strcasecmp(optarg, "MASTER") == 0) { pfs_type = HAMMER2_PFSTYPE_MASTER; } else { fprintf(stderr, "-t: Unrecognized node type\n"); usage(1); } break; case 'u': /* * set uuid for mkpfs, else one will be generated * (required for all except the MASTER node_type) */ uuid_str = optarg; break; case 'v': if (QuietOpt) --QuietOpt; else ++VerboseOpt; break; case 'q': if (VerboseOpt) --VerboseOpt; else ++QuietOpt; break; default: fprintf(stderr, "Unknown option: %c\n", ch); usage(1); /* not reached */ break; } } /* * Adjust, then process the command */ ac -= optind; av += optind; if (ac < 1) { fprintf(stderr, "Missing command\n"); usage(1); /* not reached */ } if (strcmp(av[0], "connect") == 0) { /* * Add cluster connection */ if (ac < 2) { fprintf(stderr, "connect: missing argument\n"); usage(1); } ecode = cmd_remote_connect(sel_path, av[1]); } else if (strcmp(av[0], "chaindump") == 0) { if (ac < 2) ecode = cmd_chaindump("."); else ecode = cmd_chaindump(av[1]); } else if (strcmp(av[0], "debugspan") == 0) { /* * Debug connection to the target hammer2 service and run * the CONN/SPAN protocol. */ if (ac < 2) { fprintf(stderr, "debugspan: requires hostname\n"); usage(1); } ecode = cmd_debugspan(av[1]); } else if (strcmp(av[0], "disconnect") == 0) { /* * Remove cluster connection */ if (ac < 2) { fprintf(stderr, "disconnect: missing argument\n"); usage(1); } ecode = cmd_remote_disconnect(sel_path, av[1]); } else if (strcmp(av[0], "hash") == 0) { ecode = cmd_hash(ac - 1, (const char **)(void *)&av[1]); } else if (strcmp(av[0], "status") == 0) { /* * Get status of PFS and its connections (-a for all PFSs) */ ecode = cmd_remote_status(sel_path, all_opt); } else if (strcmp(av[0], "pfs-clid") == 0) { /* * Print cluster id (uuid) for specific PFS */ if (ac < 2) { fprintf(stderr, "pfs-clid: requires name\n"); usage(1); } ecode = cmd_pfs_getid(sel_path, av[1], 0); } else if (strcmp(av[0], "pfs-fsid") == 0) { /* * Print private id (uuid) for specific PFS */ if (ac < 2) { fprintf(stderr, "pfs-fsid: requires name\n"); usage(1); } ecode = cmd_pfs_getid(sel_path, av[1], 1); } else if (strcmp(av[0], "pfs-list") == 0) { /* * List all PFSs */ ecode = cmd_pfs_list(sel_path); } else if (strcmp(av[0], "pfs-create") == 0) { /* * Create new PFS using pfs_type */ if (ac < 2) { fprintf(stderr, "pfs-create: requires name\n"); usage(1); } ecode = cmd_pfs_create(sel_path, av[1], pfs_type, uuid_str); } else if (strcmp(av[0], "pfs-delete") == 0) { /* * Delete a PFS by name */ if (ac < 2) { fprintf(stderr, "pfs-delete: requires name\n"); usage(1); } ecode = cmd_pfs_delete(sel_path, av[1]); } else if (strcmp(av[0], "snapshot") == 0) { /* * Create snapshot with optional pfs-type and optional * label override. */ if (ac > 2) { fprintf(stderr, "pfs-snapshot: too many arguments\n"); usage(1); } if (ac != 2) ecode = cmd_pfs_snapshot(sel_path, NULL); else ecode = cmd_pfs_snapshot(sel_path, av[1]); } else if (strcmp(av[0], "service") == 0) { /* * Start the service daemon. This daemon accepts * connections from local and remote clients, handles * the security handshake, and manages the core messaging * protocol. */ ecode = cmd_service(); } else if (strcmp(av[0], "stat") == 0) { ecode = cmd_stat(ac - 1, (const char **)(void *)&av[1]); } else if (strcmp(av[0], "leaf") == 0) { /* * Start the management daemon for a specific PFS. * * This will typically connect to the local master node * daemon, register the PFS, and then pass its side of * the socket descriptor to the kernel HAMMER2 VFS via an * ioctl(). The process and/or thread context remains in the * kernel until the PFS is unmounted or the connection is * lost, then returns from the ioctl. * * It is possible to connect directly to a remote master node * instead of the local master node in situations where * encryption is not desired or no local master node is * desired. This is not recommended because it represents * a single point of failure for the PFS's communications. * * Direct kernel<->kernel communication between HAMMER2 VFSs * is theoretically possible for directly-connected * registrations (i.e. where the spanning tree is degenerate), * but not recommended. We specifically try to reduce the * complexity of the HAMMER2 VFS kernel code. */ ecode = cmd_leaf(sel_path); } else if (strcmp(av[0], "shell") == 0) { /* * Connect to the command line monitor in the hammer2 master * node for the machine using HAMMER2_DBG_SHELL messages. */ ecode = cmd_shell((ac < 2) ? NULL : av[1]); } else if (strcmp(av[0], "rsainit") == 0) { /* * Initialize a RSA keypair. If no target directory is * specified we default to "/etc/hammer2". */ arg = (ac < 2) ? HAMMER2_DEFAULT_DIR : av[1]; ecode = cmd_rsainit(arg); } else if (strcmp(av[0], "rsaenc") == 0) { /* * Encrypt the input symmetrically by running it through * the specified public and/or private key files. * * If no key files are specified data is encoded using * "/etc/hammer2/rsa.pub". * * WARNING: no padding is added, data stream must contain * random padding for this to be secure. * * Used for debugging only */ if (ac == 1) { const char *rsapath = HAMMER2_DEFAULT_DIR "/rsa.pub"; ecode = cmd_rsaenc(&rsapath, 1); } else { ecode = cmd_rsaenc((const char **)(void *)&av[1], ac - 1); } } else if (strcmp(av[0], "rsadec") == 0) { /* * Decrypt the input symmetrically by running it through * the specified public and/or private key files. * * If no key files are specified data is decoded using * "/etc/hammer2/rsa.prv". * * WARNING: no padding is added, data stream must contain * random padding for this to be secure. * * Used for debugging only */ if (ac == 1) { const char *rsapath = HAMMER2_DEFAULT_DIR "/rsa.prv"; ecode = cmd_rsadec(&rsapath, 1); } else { ecode = cmd_rsadec((const char **)(void *)&av[1], ac - 1); } } else if (strcmp(av[0], "show") == 0) { /* * Raw dump of filesystem. Use -v to check all crc's, and * -vv to dump bulk file data. */ if (ac != 2) { fprintf(stderr, "show: requires device path\n"); usage(1); } else { cmd_show(av[1], 0); } } else if (strcmp(av[0], "freemap") == 0) { /* * Raw dump of freemap. Use -v to check all crc's, and * -vv to dump bulk file data. */ if (ac != 2) { fprintf(stderr, "freemap: requires device path\n"); usage(1); } else { cmd_show(av[1], 1); } } else if (strcmp(av[0], "setcomp") == 0) { if (ac < 3) { /* * Missing compression method and at least one * path. */ fprintf(stderr, "setcomp: requires compression method and" "directory/file path\n"); usage(1); } else { /* * Multiple paths may be specified */ ecode = cmd_setcomp(av[1], &av[2]); } } else if (strcmp(av[0], "printinode") == 0) { if (ac != 2) { fprintf(stderr, "printinode: requires directory/file path\n"); usage(1); } else print_inode(av[1]); } else { fprintf(stderr, "Unrecognized command: %s\n", av[0]); usage(1); } /* * In DebugMode we may wind up starting several pthreads in the * original process, in which case we have to let them run and * not actually exit. */ if (NormalExit) { return (ecode); } else { pthread_exit(NULL); _exit(2); /* NOT REACHED */ } }