// cf. OVS-1381:
// conflicting updates of volume entries could lead to an infinite loop around
// test_and_set as upon conflict detection the cached entry wasn't dropped and hence
// used in all subsequent iterations.
TEST_F(MetaDataStoreTest, conflicting_updates_for_volumes)
{
    vfs::MetaDataStore mds1(std::static_pointer_cast<yt::LockedArakoon>(registry_),
                            cluster_id_,
                            vfs::UseCache::T);

    const vfs::FrontendPath path("/volume");
    const vfs::Permissions perms(S_IWUSR bitor S_IRUSR);

    {
        vfs::DirectoryEntryPtr
            dentry(boost::make_shared<vfs::DirectoryEntry>(vfs::DirectoryEntry::Type::Volume,
                                                           mds1.alloc_inode(),
                                                           perms,
                                                           vfs::UserId(::getuid()),
                                                           vfs::GroupId(::getgid())));

        mds1.add(path, dentry);
    }

    {
        vfs::DirectoryEntryPtr dentry(mds1.find(path));
        ASSERT_TRUE(dentry != nullptr);
        ASSERT_EQ(perms, dentry->permissions());
    }

    vfs::MetaDataStore mds2(std::static_pointer_cast<yt::LockedArakoon>(registry_),
                            cluster_id_,
                            vfs::UseCache::T);

    const vfs::Permissions perms2(S_IWUSR);
    mds2.chmod(path, perms2);

    {
        vfs::DirectoryEntryPtr dentry(mds2.find(path));
        ASSERT_TRUE(dentry != nullptr);
        ASSERT_EQ(perms2, dentry->permissions());
    }

    // on mds1 the entry is cached and the change is not visible!
    {
        vfs::DirectoryEntryPtr dentry(mds1.find(path));
        ASSERT_TRUE(dentry != nullptr);
        ASSERT_EQ(perms, dentry->permissions());
    }

    const vfs::Permissions perms3(S_IRUSR);

    // this used to end up in an infinite loop around test_and_set as the cached
    // value was used in it.
    mds1.chmod(path, perms3);

    {
        vfs::DirectoryEntryPtr dentry(mds1.find(path));
        ASSERT_TRUE(dentry != nullptr);
        ASSERT_EQ(perms3, dentry->permissions());
    }
}
Esempio n. 2
0
bool FileSystem::rmtree(const Path& path) {
  Directory* test_dir = opendir(path);
  if (test_dir != NULL) {
    auto_Object<Directory> dir(test_dir);
    Directory::Entry* test_dentry = dir->read();
    if (test_dentry != NULL) {
      auto_Object<Directory::Entry> dentry(*test_dentry);

      do {
        if (dentry->is_special()) {
          continue;
        }

        Path dentry_path(path / dentry->get_name());

        if (dentry->ISDIR()) {
          if (rmtree(dentry_path)) {
            continue;
          } else {
            return false;
          }
        } else if (unlink(dentry_path)) {
          continue;
        } else {
          return false;
        }
      } while (dir->read(*dentry));

      return rmdir(path);
    }
  }

  return false;
}
TEST_F(MetaDataStoreTest, uuid_conflicting_updates_for_volumes)
{
    vfs::MetaDataStore mds1(std::static_pointer_cast<yt::LockedArakoon>(registry_),
                            cluster_id_,
                            vfs::UseCache::T);

    const vfs::DirectoryEntryPtr root_dentry(mds1.find(vfs::FrontendPath("/")));
    const vfs::ObjectId parent_id(root_dentry->object_id());

    const vfs::Permissions perms(S_IWUSR bitor S_IRUSR);
    const std::string root("volume");

    vfs::DirectoryEntryPtr
        dentry(boost::make_shared<vfs::DirectoryEntry>(vfs::DirectoryEntry::Type::Volume,
                                                       mds1.alloc_inode(),
                                                       perms,
                                                       vfs::UserId(::getuid()),
                                                       vfs::GroupId(::getgid())));
    mds1.add(parent_id, root, dentry);

    {
        vfs::DirectoryEntryPtr volume_dentry(mds1.find(dentry->object_id()));
        ASSERT_TRUE(volume_dentry != nullptr);
        ASSERT_EQ(perms, volume_dentry->permissions());
    }

    vfs::MetaDataStore mds2(std::static_pointer_cast<yt::LockedArakoon>(registry_),
                            cluster_id_,
                            vfs::UseCache::T);

    const vfs::Permissions perms2(S_IWUSR);
    mds2.chmod(dentry->object_id(), perms2);

    {
        vfs::DirectoryEntryPtr volume_dentry(mds2.find(dentry->object_id()));
        ASSERT_TRUE(volume_dentry != nullptr);
        ASSERT_EQ(perms2, volume_dentry->permissions());
    }

    {
        vfs::DirectoryEntryPtr volume_dentry(mds1.find(dentry->object_id()));
        ASSERT_TRUE(volume_dentry != nullptr);
        ASSERT_EQ(perms, volume_dentry->permissions());
    }

    const vfs::Permissions perms3(S_IRUSR);

    mds1.chmod(dentry->object_id(), perms3);

    {
        vfs::DirectoryEntryPtr volume_dentry(mds1.find(dentry->object_id()));
        ASSERT_TRUE(dentry != nullptr);
        ASSERT_EQ(perms3, volume_dentry->permissions());
    }
}
TEST_F(MetaDataStoreTest, path_and_id)
{
    vfs::MetaDataStore mds(std::static_pointer_cast<yt::LockedArakoon>(registry_),
                           cluster_id_,
                           vfs::UseCache::T);

    const vfs::FrontendPath dpath("/dir");
    const vfs::Permissions pms(S_IWUSR bitor S_IRUSR);

    vfs::DirectoryEntryPtr
        dentry(boost::make_shared<vfs::DirectoryEntry>(vfs::DirectoryEntry::Type::Directory,
                                                       mds.alloc_inode(),
                                                       pms,
                                                       vfs::UserId(::getuid()),
                                                       vfs::GroupId(::getgid())));

    mds.add(dpath,
            dentry);

    ASSERT_EQ(dpath,
              mds.find_path(dentry->object_id()));

    {
        const vfs::DirectoryEntryPtr p(mds.find(dentry->object_id()));
        ASSERT_TRUE(p != nullptr);
        ASSERT_TRUE(*dentry == *p);
    }

    const vfs::FrontendPath fpath(dpath / "file");
    vfs::DirectoryEntryPtr
        fentry(boost::make_shared<vfs::DirectoryEntry>(vfs::DirectoryEntry::Type::File,
                                                       mds.alloc_inode(),
                                                       pms,
                                                       vfs::UserId(::getuid()),
                                                       vfs::GroupId(::getgid())));

    mds.add(dentry->object_id(),
            fpath.filename().string(),
            fentry);

    ASSERT_EQ(fpath,
              mds.find_path(fentry->object_id()));

    {
        const vfs::DirectoryEntryPtr p(mds.find(fentry->object_id()));
        ASSERT_TRUE(p != nullptr);
        ASSERT_TRUE(*fentry == *p);
    }
}
TEST_F(MetaDataStoreTest, root)
{
    vfs::MetaDataStore mds(std::static_pointer_cast<yt::LockedArakoon>(registry_),
                           cluster_id_,
                           vfs::UseCache::F);

    const vfs::FrontendPath root("/");
    vfs::DirectoryEntryPtr dentry(mds.find(root));

    ASSERT_TRUE(dentry != nullptr);
    EXPECT_EQ(root,
              mds.find_path(dentry->object_id()));

    vfs::DirectoryEntryPtr dentry2(mds.find(dentry->object_id()));
    ASSERT_TRUE(dentry2 != nullptr);
}
Esempio n. 6
0
static void __init
test_pointer(void)
{
	plain();
	null_pointer();
	invalid_pointer();
	symbol_ptr();
	kernel_ptr();
	struct_resource();
	addr();
	escaped_str();
	hex_string();
	mac();
	ip();
	uuid();
	dentry();
	struct_va_format();
	struct_rtc_time();
	struct_clk();
	bitmap();
	netdev_features();
	flags();
}
Esempio n. 7
0
void
MetaDataStore::add_directories(const FrontendPath& path)
{
    LOG_TRACE(path);

    FrontendPath p;

    for (const auto& s : path)
    {
        p = FrontendPath(p / s);
        DirectoryEntryPtr dentry(find(p));

        while (true)
        {
            if (dentry == nullptr)
            {
                DirectoryEntryPtr
                    dentry(boost::make_shared<DirectoryEntry>(DirectoryEntry::Type::Directory,
                                                              alloc_inode(),
                                                              default_directory_permissions,
                                                              UserId(::getuid()),
                                                              GroupId(::getgid())));
                try
                {
                    struct timespec timebuf;
                    struct timeval tv;

                    TODO("X42: Better use fungi::IOException here? WIP");
                    int rc = clock_gettime(CLOCK_REALTIME, &timebuf);
                    if (rc != 0)
                    {
                        throw std::system_error(errno, std::system_category());
                    }

                    add(p, dentry);

                    tv.tv_sec = timebuf.tv_sec;
                    tv.tv_usec = timebuf.tv_nsec / 1000;
                    utimes(FrontendPath(p.parent_path()),
                           tv,
                           tv);
                    break;
                }
                catch (FileExistsException&)
                {
                    LOG_WARN(p << ": someone else created an eponymous entry at the same time");
                }
            }
            else
            {
                if (dentry->type() != DirectoryEntry::Type::Directory)
                {
                    LOG_ERROR(p << " already exists but is not a directory");
                    throw fungi::IOException("Entry is not a directory",
                                             p.string().c_str(),
                                             ENOTDIR);
                }

                break;
            }
        }
    }
}