⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfsrodb.c

📁 chord 源码 http://pdos.csail.mit.edu/chord/
💻 C
📖 第 1 页 / 共 2 页
字号:
  inode->reg->size = inode->reg->used = calllen;  inode->reg->direct.setsize (1);  inode->reg->direct[0] = *fh;  //  strbuf sb;  //rpc_print (sb, *inode, 5, NULL, " ");  //warn << "storedirectory " << sb << "\n";  return;}static intcompare_name (const void *file1, const void *file2){  return (strcmp (*(static_cast < char * const*>(file1)),		  *(static_cast < char * const*>(file2))));}voidsort_dir (const str path, vec < char *>&file_list){  DIR *dirp;  struct dirent *de = NULL;  char *filename;  if ((dirp = opendir (path)) == 0) {    warn << path << " is not a directory\n";    return;  }  while ((de = readdir (dirp))) {    // XXX memory leak!!!!    filename = New char[strlen (de->d_name) + 1];    memcpy (filename, de->d_name, strlen (de->d_name) + 1);    file_list.push_back (filename);  }  //  // XXX this might be broken.... --josh  //  qsort (file_list.base (), file_list.size (),	 sizeof (char *), compare_name);  if (closedir (dirp) < 0) {    warn << "closedir failed: " << path << ": " << strerror (errno) << "\n";    exit (0);  }}/* pseudo-destructor */voidtwiddle_sort_dir (vec < char *>&file_list){  for (unsigned int i = 0; i < file_list.size (); i++) {    delete file_list[i];  }}// XXX keep in sync with same function in chordcd/server.Cstatic uint64path2fileid(const str path){  char buf[sha1::hashsize];  bzero(buf, sha1::hashsize);  sha1_hash (buf, path.cstr (), path.len ());  return gethyper (buf); // XXX not using all 160 bits of the hash}static voidsplitpath (vec<str> &out, str in){  const char *p = in.cstr ();  const char *e = p + in.len ();  const char *n;  for (;;) {    while (*p == '/')      p++;    for (n = p; n < e && *n != '/'; n++)      ;    if (n == p)      return;    out.push_back (str (p, n - p));    p = n;  }    }/* Given a path, split it into two pieces:   the parent directory path and the filename.   Examples:   path      parent   filename   "/"       "/"      ""   "/a"      "/"      "a"   "/a/"     "/"      "a"   "/a/b"    "/a"     "b"   "/a/b/c"  "/a/b"   "c"*/static voidparentpath (str &parent, str &filename, const str inpath){  vec<str> ppv;  parent = str ("/");  filename = str ("");  splitpath (ppv, inpath);  if (ppv.size () == 0)    return;  filename = ppv.pop_back ();  if (ppv.size () == 0)    return;  // What a non-intuitive way to do concatenation!  parent = strbuf () << "/" << join (str("/"), ppv);}static strparentpath (const str fullpath){  str p;  str c;  parentpath (p, c, fullpath);  return p;}/*   Given: Path to file (any kind), an allocated fh, the inode   number of the path's parent   Path is like '/','/a','/a/b' (ie only the root ends in slash)   Return: The hash and IV in the fh.   Effects: Recursively hash everything beneath a directory   It computes the cryptographic file handle for the   given path, inserts the mapping from the fh to its data */str timestamp = "";intrecurse_path (const str path, sfs_hash * fh){  str fspath = strbuf () << "/" << timestamp << substr (path, relpathlen);  struct stat st;  if (lstat (path, &st) < 0)    fatal << path << ": " << strerror(errno) << "\n";    sfsro_inode inode;  if (S_ISLNK (st.st_mode)) {        char *buf = New char[st.st_size + 1];    int nchars = readlink (path, buf, st.st_size);    if (nchars > MAXPATHLEN) {      warn << "symlink target too large "	<< path << " " << nchars << "\n";      return -1;    }    sfsrodb_setinode (&st, fspath, &inode);    inode.lnk->dest = nfspath3 (buf, nchars);    delete[] buf;  } else if (S_ISREG (st.st_mode)) {    sfsrodb_setinode (&st, fspath, &inode);    store_file (&inode, path);  }  else if (S_ISDIR (st.st_mode)) {    sfsrodb_setinode (&st, fspath, &inode);    vec < char *>file_list;    sort_dir (path, file_list);    sfsro_data directory (SFSRO_DIRBLK);    directory.dir->eof = true;    rpc_ptr < sfsro_dirent > *direntp = &directory.dir->entries;    for (unsigned int i = 0; i < file_list.size (); i++) {      (*direntp).alloc ();      (*direntp)->name = file_list[i];      if ((*direntp)->name.cmp (".") == 0) 	(*direntp)->fileid = path2fileid(path);      else if ((*direntp)->name.cmp ("..") == 0)	(*direntp)->fileid = path2fileid(parentpath(path));      else {	str childpath = path << "/" << (*direntp)->name;	(*direntp)->fileid = path2fileid(childpath);	recurse_path (childpath, &(*direntp)->fh);      }      direntp = &(*direntp)->nextentry;    }     twiddle_sort_dir (file_list);    store_directory (&inode, fh, &directory);  }  else {    warn << "Not symlink, reg file, or directory " << path << "\n";    return -1;  }  store_inode (&inode, fh);  return 0;}boolget_root_inode_and_dir (bigint rootkey, sfsro_inode *rootino, sfsro_data *rootdir){  // fetch the filesystem root.  //    ptr<sfsro_data> root_dat = sfsrodb_get (rootkey, DHASH_KEYHASH);  if (!root_dat) {    warn << "root block was null\n";    return false;  } else if (root_dat->type != CFS_FSINFO) {    warn << "root block has wrong type: " << root_dat->type << "\n";    return false;  }   // fetch the root inode  //  ptr<sfsro_data> rootino_dat = sfsrodb_get (root_dat->fsinfo->rootfh, DHASH_CONTENTHASH);  if (!rootino_dat) {    warn << "root inode block was null\n";    return false;  } else if (rootino_dat->type != SFSRO_INODE) {    warn << "(1) bad type on inode block: " << rootino_dat->type << "\n";    return false;  } else if (rootino_dat->inode->type != SFSRODIR) {    warn << "(2) bad type on inode block: " << rootino_dat->inode->type << "\n";    return false;  } else if (rootino_dat->inode->reg->direct.size () != 1) {    warn << "root inode, expected only one direct block: " <<      rootino_dat->inode->reg->direct.size () << "\n";    return false;  }  // fetch the root directory  //  bigint d0;  sfs_hash *tmp = &rootino_dat->inode->reg->direct[0];  mpz_set_rawmag_be(&d0, tmp->base (), tmp->size ());  // For big endian  ptr<sfsro_data> rootdir_dat = sfsrodb_get (d0, DHASH_CONTENTHASH);  if (!rootdir_dat) {    warn << "root directory was null\n";    return false;  } else if (rootdir_dat->type != SFSRO_DIRBLK) {    warn << "root directory bad type: " << rootdir_dat->type << "\n";    return false;  }   *rootino = *rootino_dat->inode;  *rootdir = *rootdir_dat;  return true;}intsfsrodb_main (const str root, const str keyfile){  time_t start = time (NULL);  str stime (ctime (&start));  if (x_flag) {    timestamp = substr (stime, 0, stime.len () - 1); // trim newline    //timestamp = "SHIT";  }  dhash_cli = New refcounted <dhashclient> (lsd_socket);  ptr <sfspriv> sk;  if (!keyfile) {    warn << "cannot locate default file sfs_host_key\n";    fatal ("errors!\n");  }  else {    str key = file2wstr (keyfile);    if (!key) {      warn << keyfile << ": " << strerror (errno) << "\n";      fatal ("errors!\n");    }    else if (!(sk = sfscrypt.alloc_priv (key, SFS_DECRYPT | SFS_SIGN))) {      warn << "could not decode " << keyfile << "\n";      warn << key << "\n";      fatal ("errors!\n");    }  }  strbuf b;  if (!sk->export_pubkey (b, false)) {    warn << "could not set public key: " << keyfile << "\n";    fatal ("errors!\n");  }  str pk_raw = b;  bigint pk_hash_bi = compute_hash (pk_raw.cstr (), pk_raw.len ());  // store file system in db  sfs_hash root_fh;  relpathlen = root.len ();  recurse_path (root, &root_fh);  // for the sake of debugging output, wait for all puts to finish...  while (out) acheck ();   if (x_flag) {    // -------------------------------------------------    sfsro_inode inode (SFSRODIR);    sfsro_data directory (SFSRO_DIRBLK);        rpc_ptr < sfsro_dirent > *direntp = &directory.dir->entries;    bool found = false;    if (!wipe_flag)      found = get_root_inode_and_dir (pk_hash_bi, &inode, &directory);    // XXX is something wrong with pk_hash_bi???    if (wipe_flag || !found) {      // fake up an empty directory      directory.dir->eof = true;            (*direntp).alloc ();      (*direntp)->name = ".";      (*direntp)->fileid = path2fileid ("/");      direntp = &(*direntp)->nextentry;            (*direntp).alloc ();      (*direntp)->name = "..";      (*direntp)->fileid = path2fileid ("/");      direntp = &(*direntp)->nextentry;    }        // skip to the end    while (*direntp)      direntp = &(*direntp)->nextentry;        // append new entry    (*direntp).alloc ();    (*direntp)->name = timestamp;    (*direntp)->fileid = path2fileid (strbuf() << "/" << timestamp);    (*direntp)->fh = root_fh;    direntp = &(*direntp)->nextentry;    sfs_hash junk;    store_directory (&inode, &junk, &directory);    store_inode (&inode, &root_fh);#if 0    rpc_ptr < sfsro_dirent > *dp = &directory.dir->entries;    while (*dp) {      warn << ">>> " << (*dp)->name << "\n";      dp = &(*dp)->nextentry;    }#endif  }  // -------------------------------------------------  sfsro_data dat (CFS_FSINFO);  dat.fsinfo->start = start;  dat.fsinfo->duration = sfsro_duration;  dat.fsinfo->rootfh = fh2mpz (root_fh.base (), root_fh.size ());  dat.fsinfo->blocksize = blocksize;  time_t end = dat.fsinfo->start + dat.fsinfo->duration;  // XX Should make sure timezone is correct  str etime (ctime (&end));  warn << "Database good from: \n " << stime << "until:\n " << etime;  xdrsuio x (XDR_ENCODE);  if (xdr_sfsro_data (x.xdrp (), &dat)) {    void *v = suio_flatten (x.uio ());    int l =  x.uio ()->resid ();    chordID ID = sfsrodb_put (sk, v, l);    warn << "exported file system under " << ID << "\n";    xfree (v);  }  if (verbose_mode) {    warn << "identical blocks:   " << identical_block << "\n";    warn << "identical sindirs:  " << identical_sindir << "\n";    warn << "identical dindirs:  " << identical_dindir << "\n";    warn << "identical tindirs:  " << identical_tindir << "\n";    warn << "identical dirs:     " << identical_dir << "\n";    warn << "identical inodes:   " << identical_inode << "\n";    warn << "identical symlinks: " << identical_sym << "\n";    warn << "Database contents:\n";    warn << "Regular inodes:      " << reginode_cnt << "\n";    warn << "Symlink inodes:      " << lnkinode_cnt << "\n";    warn << "Directory blocks     " << directory_cnt << "\n";    warn << "File data blocks:    " << filedatablk_cnt << "\n";    warn << "Single indir blocks: " << sindir_cnt << "\n";    warn << "Double indir blocks: " << dindir_cnt << "\n";    warn << "Triple indir blocks: " << tindir_cnt << "\n";    warn << "identical fh's overall : " << identical_fh << "\n";    warn << "unique fh's overall    : " << fh_cnt << "\n\n\n";  }    while (out) acheck ();  return 0;}static voidusage (){  warnx << "usage: " << progname	<< " -d <export directory> -s <SK keyfile> -o <dbfile>\n";  warnx << "              [-i] [-h <hostname for db>] [-v] [-b <blocksize>]\n";  warnx << "-d <export directory> : The directory hierarchy to export\n";  warnx << "-s <SK keyfile>       : Path to the secret key file\n";  warnx << "Optional directives:\n";  warnx << "-v                    : Verbose debugging output\n";  warnx << "-b <blocksize>        : Page size of underlying database\n";  warnx << "Backup directives:\n";  warnx << "-x                    : do backup\n";  warnx << "-w                    : wipe the root directory clean\n";   exit (1);}intmain (int argc, char **argv){  setprogname (argv[0]);  char *exp_dir = NULL;  char *sk_file = NULL;    verbose_mode = false;  initialize = false;  blocksize = 8192;  lsd_socket = "/tmp/chord-sock";  int ch;  while ((ch = getopt (argc, argv, "b:d:s:S:vwx")) != -1)    switch (ch) {    case 'b':      if (!convertint (optarg, &blocksize)	  || blocksize < 512 || blocksize > 0x400000)	usage ();      break;    case 'd':      exp_dir = optarg;      break;    case 's':      sk_file = optarg;      break;    case 'v':      verbose_mode = true;      break;    case 'w':      wipe_flag = true;      break;    case 'x':      x_flag = true;      break;    case 'S':      lsd_socket = optarg;      break;    case '?':    default:      usage ();    }  argc -= optind;  argv += optind;  nfh = (blocksize - 100) / (sha1::hashsize*2);  if ( (argc > 0) || !exp_dir || !sk_file )    usage ();  if (wipe_flag && !x_flag) {    warn << "-w but not -x??\n";    usage ();  }  if (verbose_mode) {    warnx << "export directory : " << exp_dir << "\n";    warnx << "SK keyfile       : " << sk_file << "\n";  }  sigcb(SIGUSR1, wrap (&sfsrodb_core_sigusr1));  return (sfsrodb_main (exp_dir, sk_file));}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -