예제 #1
0
void NodeSystem::rename(FUSE::Handle sourceHandle, const std::string& sourceName, FUSE::Handle destHandle, const std::string& destName) {
    auto& sourceNode = getNodeInfo(sourceHandle).node;
    auto& destNode = getNodeInfo(destHandle).node;

    const auto sourcePath = getPath(sourceHandle) + sourceName;
    const auto destPath = getPath(destHandle) + destName;

    if (sourcePath.hasChild(destPath)) {
        // Can't rename to a subdirectory of itself.
        throw FUSE::ErrorException(EINVAL);
    }

    if (sourcePath == destPath) {
        // Paths are the same; nothing to do.
        return;
    }

    Directory sourceDirectory(sourceNode);
    Directory destDirectory(destNode);

    if (!sourceDirectory.hasChild(sourceName)) {
        throw FUSE::ErrorException(ENOENT);
    }

    destDirectory.forceAddChild(destName, sourceDirectory.getChild(sourceName));
    sourceDirectory.removeChild(sourceName);

    // Re-map any affected metadata.
    removeAllMetadata(destPath);
    moveAllMetadata(sourcePath, destPath);

    // Re-map any affected handles.
    detachAllHandles(destPath);
    moveAllHandles(sourcePath, destPath);
}
예제 #2
0
inline
bool
NdbImpl::getIsDbNode(NodeId n) const {
  return
    getNodeInfo(n).defined &&
    getNodeInfo(n).m_info.m_type == NodeInfo::DB;
}
예제 #3
0
FUSE::Handle NodeSystem::openChild(FUSE::Handle parentHandle, const std::string& name) {
    printf("Opening child '%s' of directory with handle %llu.\n",
           name.c_str(), (unsigned long long) parentHandle);

    auto& parentNodeInfo = getNodeInfo(parentHandle);

    if (parentNodeInfo.node.type() != TYPE_DIRECTORY) {
        throw FUSE::ErrorException(ENOTDIR);
    }

    // Get child path.
    const auto path = getPath(parentHandle) + name;

    // Check if the node is already open.
    const auto iterator = pathToHandleMap_.find(path);

    if (iterator != pathToHandleMap_.end()) {
        const auto handle = iterator->second;
        getNodeInfo(handle).refCount++;
        return iterator->second;
    }

    // Get the child's block ID from the parent.
    Directory directory(parentNodeInfo.node);

    if (!directory.hasChild(name)) {
        throw FUSE::ErrorException(ENOENT);
    }

    const auto childBlockId = directory.getChild(name);

    // Create a node.
    auto nodeInfoPtr = std::unique_ptr<NodeInfo>(new NodeInfo(database_, childBlockId, metadata_.at(path)));

    // Generate a new handle.
    const auto handle = nextHandle_++;

    printf("Allocating handle %llu.\n",
           (unsigned long long) handle);

    handleToNodeMap_.emplace(handle, std::move(nodeInfoPtr));

    // Create the bi-directional mapping between handle and path.
    pathToHandleMap_.emplace(path, handle);
    handleToPathMap_.emplace(handle, path);

    return handle;
}
예제 #4
0
FUSE::Handle NodeSystem::openRoot() {
    printf("Opening root.\n");
    const auto path = FUSE::Path();

    // Check if the node is already open.
    const auto iterator = pathToHandleMap_.find(path);

    if (iterator != pathToHandleMap_.end()) {
        const auto handle = iterator->second;
        getNodeInfo(handle).refCount++;
        return iterator->second;
    }

    // Create a node.
    auto nodeInfoPtr = std::unique_ptr<NodeInfo>(new NodeInfo(database_, rootId_, metadata_.at(path)));

    // Generate a new handle.
    const auto handle = nextHandle_++;

    handleToNodeMap_.emplace(handle, std::move(nodeInfoPtr));

    // Create the bi-directional mapping between handle and path.
    pathToHandleMap_.emplace(path, handle);
    handleToPathMap_.emplace(handle, path);

    return handle;
}
예제 #5
0
void NodeSystem::flushNode(FUSE::Handle handle) {
    printf("Flushing handle %llu.\n",
           (unsigned long long) handle);

    auto& nodeInfo = getNodeInfo(handle);

    // Get the node's path; this won't be
    // available if it has been detached,
    // in which case nothing needs to be done.
    const auto pathIterator = handleToPathMap_.find(handle);

    if (pathIterator != handleToPathMap_.end()) {
        const auto& path = pathIterator->second;

        if (nodeInfo.node.hasChanged()) {
            nodeInfo.metadata.updateModifyTime();

            // Perform a cascade update.
            nodeInfo.node.flush();
            rootId_ = cascadeUpdate(path, nodeInfo.node.blockId());
        } else {
            nodeInfo.metadata.updateAccessTime();
        }

        metadata_.at(path) = nodeInfo.metadata;
    }
}
예제 #6
0
BlockId NodeSystem::cascadeUpdate(const FUSE::Path& path, BlockId newId) {
    printf("Performing cascade for path %s.\n", path.toString().c_str());

    std::stack<HandleRef> refStack;
    refStack.push(HandleRef(*this, openRoot()));

    for (size_t i = 1; i < path.size(); i++) {
        refStack.push(HandleRef(*this, openChild(refStack.top().get(), path.at(i - 1))));
    }

    BlockId blockId = newId;

    for (size_t i = 0; i < path.size(); i++) {
        const size_t pos = path.size() - i - 1;
        printf("Updating block ID for component %llu.\n",
               (unsigned long long) pos);
        printf("Updating block ID for component %llu: '%s'.\n",
               (unsigned long long) pos,
               path.at(pos).c_str());

        auto& parentNode = getNodeInfo(refStack.top().get()).node;
        Directory directory(parentNode);
        directory.updateChild(path.at(pos), blockId);

        parentNode.flush();

        blockId = parentNode.blockId();

        refStack.pop();
    }

    return blockId;
}
예제 #7
0
void InfoFileExporter::visit(const scene::INodePtr& node)
{
    // Don't export the layer settings for models and particles, as they are not there
    // at map load/parse time - these shouldn't even be passed in here
    assert(node && !Node_isModel(node) && !particles::isParticleNode(node));

    // Open a Node block
    _stream << "\t\t" << InfoFile::NODE << " { ";

    scene::LayerList layers = node->getLayers();

    // Write a space-separated list of node IDs
    for (scene::LayerList::const_iterator i = layers.begin(); i != layers.end(); ++i)
    {
        _stream << *i << " ";
    }
    
    // Close the Node block
    _stream << "}";

    // Write additional node info, for easier debugging of layer issues
    _stream << " // " << getNodeInfo(node);

    _stream << std::endl;

    _layerInfoCount++;
}
예제 #8
0
inline
bool
NdbImpl::get_node_stopping(NodeId n) const {
  const trp_node & node = getNodeInfo(n);
  assert(node.m_info.getType() == NodeInfo::DB);
  return (!node.m_state.getSingleUserMode() &&
          node.m_state.startLevel >= NodeState::SL_STOPPING_1);
}
예제 #9
0
void
Trpman::execENABLE_COMREQ(Signal* signal)
{
  jamEntry();
  const EnableComReq *enableComReq = (const EnableComReq *)signal->getDataPtr();

  /* Need to copy out signal data to not clobber it with sendSignal(). */
  BlockReference senderRef = enableComReq->m_senderRef;
  Uint32 senderData = enableComReq->m_senderData;
  Uint32 nodes[NodeBitmask::Size];
  MEMCOPY_NO_WORDS(nodes, enableComReq->m_nodeIds, NodeBitmask::Size);

  /* Enable communication with all our NDB blocks to these nodes. */
  Uint32 search_from = 1;
  for (;;)
  {
    Uint32 tStartingNode = NodeBitmask::find(nodes, search_from);
    if (tStartingNode == NodeBitmask::NotFound)
      break;
    search_from = tStartingNode + 1;

    if (!handles_this_node(tStartingNode))
      continue;
    globalTransporterRegistry.setIOState(tStartingNode, NoHalt);
    setNodeInfo(tStartingNode).m_connected = true;

    //-----------------------------------------------------
    // Report that the version of the node
    //-----------------------------------------------------
    signal->theData[0] = NDB_LE_ConnectedApiVersion;
    signal->theData[1] = tStartingNode;
    signal->theData[2] = getNodeInfo(tStartingNode).m_version;
    signal->theData[3] = getNodeInfo(tStartingNode).m_mysql_version;

    sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 4, JBB);
    //-----------------------------------------------------
  }

  EnableComConf *enableComConf = (EnableComConf *)signal->getDataPtrSend();
  enableComConf->m_senderRef = reference();
  enableComConf->m_senderData = senderData;
  MEMCOPY_NO_WORDS(enableComConf->m_nodeIds, nodes, NodeBitmask::Size);
  sendSignal(senderRef, GSN_ENABLE_COMCONF, signal,
             EnableComConf::SignalLength, JBA);
}
예제 #10
0
void NodeSystem::resizeFile(FUSE::Handle handle, size_t size) {
    auto& node = getNodeInfo(handle).node;

    if (node.type() != TYPE_FILE) {
        throw FUSE::ErrorException(EISDIR);
    }

    node.resize(size);
}
예제 #11
0
std::vector<std::string> NodeSystem::readDirectory(FUSE::Handle handle) const {
    auto& node = getNodeInfo(handle).node;

    if (node.type() != TYPE_DIRECTORY) {
        throw FUSE::ErrorException(ENOTDIR);
    }

    Directory directory(node);
    return directory.childNames();
}
예제 #12
0
void Cmvmi::execCONNECT_REP(Signal *signal){
  const Uint32 hostId = signal->theData[0];
  jamEntry();
  
  const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type;
  ndbrequire(type != NodeInfo::INVALID);
  globalData.m_nodeInfo[hostId].m_version = 0;
  globalData.m_nodeInfo[hostId].m_signalVersion = 0;
  
  if(type == NodeInfo::DB || globalData.theStartLevel >= NodeState::SL_STARTED){
    jam();
    
    /**
     * Inform QMGR that client has connected
     */

    signal->theData[0] = hostId;
    sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
  } else if(globalData.theStartLevel == NodeState::SL_CMVMI ||
            globalData.theStartLevel == NodeState::SL_STARTING) {
    jam();
    /**
     * Someone connected before start was finished
     */
    if(type == NodeInfo::MGM){
      jam();
      signal->theData[0] = hostId;
      sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
    } else {
      /**
       * Dont allow api nodes to connect
       */
      ndbout_c("%d %d %d", hostId, type, globalData.theStartLevel);
      abort();
      globalTransporterRegistry.do_disconnect(hostId);
    }
  }
  
  /* Automatically subscribe events for MGM nodes.
   */
  if(type == NodeInfo::MGM){
    jam();
    globalTransporterRegistry.setIOState(hostId, NoHalt);
  }

  //------------------------------------------
  // Also report this event to the Event handler
  //------------------------------------------
  signal->theData[0] = NDB_LE_Connected;
  signal->theData[1] = hostId;
  signal->header.theLength = 2;
  
  execEVENT_REP(signal);
}
예제 #13
0
size_t NodeSystem::readFile(FUSE::Handle handle, size_t offset, uint8_t* buffer, size_t size) const {
    // printf("Read %llu bytes from handle %llu.\n", (unsigned long long) size, (unsigned long long) handle);

    auto& node = getNodeInfo(handle).node;

    if (node.type() != TYPE_FILE) {
        throw FUSE::ErrorException(EISDIR);
    }

    return node.read(offset, buffer, size);
}
예제 #14
0
size_t NodeSystem::writeFile(FUSE::Handle handle, size_t offset, const uint8_t* buffer, size_t size) {
    // printf("Write %llu bytes to handle %llu.\n", (unsigned long long) size, (unsigned long long) handle);

    auto& node = getNodeInfo(handle).node;

    if (node.type() != TYPE_FILE) {
        throw FUSE::ErrorException(EISDIR);
    }

    return node.write(offset, buffer, size);
}
예제 #15
0
/**
 * execROUTE_ORD
 * Allows other blocks to route signals as if they
 * came from TRPMAN
 * Useful in ndbmtd for synchronising signals w.r.t
 * external signals received from other nodes which
 * arrive from the same thread that runs TRPMAN
 */
void
Trpman::execROUTE_ORD(Signal* signal)
{
  jamEntry();
  if (!assembleFragments(signal))
  {
    jam();
    return;
  }

  SectionHandle handle(this, signal);

  RouteOrd* ord = (RouteOrd*)signal->getDataPtr();
  Uint32 dstRef = ord->dstRef;
  Uint32 srcRef = ord->srcRef;
  Uint32 gsn = ord->gsn;
  /* ord->cnt ignored */

  Uint32 nodeId = refToNode(dstRef);

  if (likely((nodeId == 0) ||
             getNodeInfo(nodeId).m_connected))
  {
    jam();
    Uint32 secCount = handle.m_cnt;
    ndbrequire(secCount >= 1 && secCount <= 3);

    jamLine(secCount);

    /**
     * Put section 0 in signal->theData
     */
    Uint32 sigLen = handle.m_ptr[0].sz;
    ndbrequire(sigLen <= 25);
    copy(signal->theData, handle.m_ptr[0]);

    SegmentedSectionPtr save = handle.m_ptr[0];
    for (Uint32 i = 0; i < secCount - 1; i++)
      handle.m_ptr[i] = handle.m_ptr[i+1];
    handle.m_cnt--;

    sendSignal(dstRef, gsn, signal, sigLen, JBB, &handle);

    handle.m_cnt = 1;
    handle.m_ptr[0] = save;
    releaseSections(handle);
    return ;
  }

  releaseSections(handle);
  warningEvent("Unable to route GSN: %d from %x to %x",
	       gsn, srcRef, dstRef);
}
예제 #16
0
inline
bool
NdbImpl::getIsNodeSendable(NodeId n) const {
  const trp_node & node = getNodeInfo(n);
  const Uint32 startLevel = node.m_state.startLevel;
  const NodeInfo::NodeType node_type = node.m_info.getType();
  assert(node_type == NodeInfo::DB ||
         node_type == NodeInfo::MGM);

  return node.compatible && (startLevel == NodeState::SL_STARTED ||
                             startLevel == NodeState::SL_STOPPING_1 ||
                             node.m_state.getSingleUserMode() ||
                             node_type == NodeInfo::MGM);
}
예제 #17
0
NodeId
SignalSender::find_node(const NodeBitmask& mask, T & t)
{
    unsigned n= 0;
    do {
        n= mask.find(n+1);

        if (n == NodeBitmask::NotFound)
            return 0;

        assert(n < MAX_NODES);

    } while (!t.found_ok(*this, getNodeInfo(n)));

    return n;
}
예제 #18
0
/**
 * Server function that listens for messages from clients
 */
void *server(void *token)
{
  me.self = setupNode();
  char message[BUFFER_LENGTH];
  int numNodes = 0;
  char *line = NULL;
  size_t len = 0;
  ssize_t read;

  do {
    //sleep(3);
    me.endpoints_fp = fopen(ENDPOINTS, "a+");
  } while (me.endpoints_fp == NULL);

  while ((read = getline(&line, &len, me.endpoints_fp)) != -1) {
    line[read - 1] = '\0';
    read--;
    numNodes++;
    debug("Read %s from endpoints file", line);
  }
  me.id = numNodes;
  debug("Done reading endpoints file, we have id: %d", me.id);

  if (args.num_nodes - 1 == numNodes) {
    debug("We are the last process");
    me.last_process = TRUE;
  }
  fprintf(me.endpoints_fp, "%s\n", getNodeInfo(me.self));
  debug("Node info written to endpoints file");
  fclose(me.endpoints_fp);

  if (!me.last_process) {
    // wait for OK message
    debug("Waiting for \"OK\" message");
    if (recvfrom(me.self->socket, message, BUFFER_LENGTH, 0, NULL, NULL) == -1) {
      log_err("Failed to receive message");
    }
    debug("Received message %s", message);
    if (strcmp(message, "OK") == 0) {
      debug("Got the \"OK\"");
    }
  }

  pthread_barrier_wait(&me.barrier);
  free(line);
  server_listen(message);
}
예제 #19
0
void Cmvmi::execENABLE_COMORD(Signal* signal)
{
  // Enable communication with all our NDB blocks to this node
  
  Uint32 tStartingNode = signal->theData[0];
  globalTransporterRegistry.setIOState(tStartingNode, NoHalt);
  setNodeInfo(tStartingNode).m_connected = true;
    //-----------------------------------------------------
  // Report that the version of the node
  //-----------------------------------------------------
  signal->theData[0] = NDB_LE_ConnectedApiVersion;
  signal->theData[1] = tStartingNode;
  signal->theData[2] = getNodeInfo(tStartingNode).m_version;

  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
  //-----------------------------------------------------
  
  jamEntry();
}
예제 #20
0
void NodeSystem::addChild(FUSE::Handle handle, const std::string& name, bool isDirectory) {
    auto& parentNode = getNodeInfo(handle).node;

    if (parentNode.type() != TYPE_DIRECTORY) {
        throw FUSE::ErrorException(ENOTDIR);
    }

    const auto path = getPath(handle) + name;

    Directory directory(parentNode);

    if (directory.hasChild(name)) {
        throw FUSE::ErrorException(EEXIST);
    }

    directory.addChild(name, isDirectory ? emptyDir_ : emptyFile_);

    // Add metadata information.
    metadata_.emplace(path, Metadata::Now());
}
예제 #21
0
State::stateResult_t OccRenderer::showCulled(FrameContext & context,Node * rootNode, const RenderParam & rp){
	std::deque<Node *> nodes;
	nodes.push_back(rootNode);
	while(!nodes.empty()){
		Node * node=nodes.front();
		nodes.pop_front();
		NodeInfo * nInfo=getNodeInfo(node);

		if(!conditionalFrustumTest(context.getCamera()->getFrustum(), node->getWorldBB(), rp))
			continue;
		else if(node->isClosed() ){
			if(nInfo->getVisibleFrameNumber()!=frameNumber)
				context.displayNode(node,rp);
		}else {
			const auto children = getChildNodes(node);
			nodes.insert(nodes.end(), children.begin(), children.end());
		}
	}
	return State::STATE_SKIP_RENDERING;
}
예제 #22
0
void
Trpman::execDISCONNECT_REP(Signal *signal)
{
  const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
  const Uint32 hostId = rep->nodeId;
  jamEntry();

  setNodeInfo(hostId).m_connected = false;
  setNodeInfo(hostId).m_connectCount++;
  const NodeInfo::NodeType type = getNodeInfo(hostId).getType();
  ndbrequire(type != NodeInfo::INVALID);

  sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal,
             DisconnectRep::SignalLength, JBA);

  signal->theData[0] = hostId;
  sendSignal(CMVMI_REF, GSN_CANCEL_SUBSCRIPTION_REQ, signal, 1, JBB);

  signal->theData[0] = NDB_LE_Disconnected;
  signal->theData[1] = hostId;
  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
예제 #23
0
void Cmvmi::execDISCONNECT_REP(Signal *signal)
{
  const DisconnectRep * const rep = (DisconnectRep *)&signal->theData[0];
  const Uint32 hostId = rep->nodeId;
  const Uint32 errNo  = rep->err;
  
  jamEntry();

  setNodeInfo(hostId).m_connected = false;
  setNodeInfo(hostId).m_connectCount++;
  const NodeInfo::NodeType type = getNodeInfo(hostId).getType();
  ndbrequire(type != NodeInfo::INVALID);

  sendSignal(QMGR_REF, GSN_DISCONNECT_REP, signal, 
             DisconnectRep::SignalLength, JBA);
  
  cancelSubscription(hostId);

  signal->theData[0] = NDB_LE_Disconnected;
  signal->theData[1] = hostId;
  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
예제 #24
0
// GSN_EXEC_FRAGCONF
void
DblqhProxy::execEXEC_FRAGCONF(Signal* signal)
{
  Uint32 ref = signal->theData[1];

  if (refToNode(ref) == getOwnNodeId())
  {
    jam();
    sendSignal(ref, GSN_EXEC_FRAGCONF, signal, 1, JBB);
  }
  else if (ndb_route_exec_frag(getNodeInfo(refToNode(ref)).m_version))
  {
    jam();
    sendSignal(numberToRef(DBLQH, refToNode(ref)), GSN_EXEC_FRAGCONF,
               signal, 2, JBB);
  }
  else
  {
    jam();
    sendSignal(ref, GSN_EXEC_FRAGCONF, signal, 2, JBB);
  }
}
예제 #25
0
/**
 * (internal)
 */
void OccRenderer::processNode(FrameContext & context,Node * node,NodeInfo * nodeInfo,NodeDistancePriorityQueue_F2B & distanceQueue,const RenderParam & rp){
	if (!node->isActive())
		return;

	nodeInfo->setProcessedFrameNumber(frameNumber);

	if(node->isClosed()){
		context.displayNode(node, rp );
	}else{
		const auto children = getChildNodes(node);
		for(auto & child : children){
			NodeInfo * i=getNodeInfo(child);
			if( rp.getFlag(FRUSTUM_CULLING) && i->getActualFrustumStatus()==Geometry::Frustum::OUTSIDE) //context.getCamera()->testBoxFrustumIntersection( (*it)->getWorldBB()) == Frustum::OUTSIDE )
				continue;
			if( i->getActualSubtreeComplexity() == 0){
				continue;
			}

			distanceQueue.push(child);
		}
	}
}
예제 #26
0
void
ClusterMgr::print_nodes(const char* where, NdbOut& out)
{
    out << where << " >>" << endl;
    for (NodeId n = 1; n < MAX_NODES ; n++)
    {
        const trp_node node = getNodeInfo(n);
        if (!node.defined)
            continue;
        out << "node: " << n << endl;
        out << " -";
        out << " connected: " << node.is_connected();
        out << ", compatible: " << node.compatible;
        out << ", nf_complete_rep: " << node.nfCompleteRep;
        out << ", alive: " << node.m_alive;
        out << ", confirmed: " << node.is_confirmed();
        out << endl;

        out << " - " << node.m_info << endl;
        out << " - " << node.m_state << endl;
    }
    out << "<<" << endl;
}
예제 #27
0
// GSN_EXEC_FRAGREQ
void
DblqhProxy::execEXEC_FRAGREQ(Signal* signal)
{
  Uint32 ref = ((ExecFragReq*)signal->getDataPtr())->dst;

  if (refToNode(ref) == getOwnNodeId())
  {
    jam();
    sendSignal(ref, GSN_EXEC_FRAGREQ, signal, signal->getLength(), JBB);
  }
  else if (ndb_route_exec_frag(getNodeInfo(refToNode(ref)).m_version))
  {
    jam();
    sendSignal(numberToRef(DBLQH, refToNode(ref)), GSN_EXEC_FRAGREQ, signal,
               signal->getLength(), JBB);
  }
  else
  {
    jam();
    sendSignal(ref, GSN_EXEC_FRAGREQ, signal,
               signal->getLength(), JBB);
  }
}
예제 #28
0
void
Trpman::execCONNECT_REP(Signal *signal)
{
  const Uint32 hostId = signal->theData[0];
  jamEntry();

  const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type;
  ndbrequire(type != NodeInfo::INVALID);

  /**
   * Inform QMGR that client has connected
   */
  signal->theData[0] = hostId;
  if (ERROR_INSERTED(9005))
  {
    sendSignalWithDelay(QMGR_REF, GSN_CONNECT_REP, signal, 50, 1);
  }
  else
  {
    sendSignal(QMGR_REF, GSN_CONNECT_REP, signal, 1, JBA);
  }

  /* Automatically subscribe events for MGM nodes.
   */
  if (type == NodeInfo::MGM)
  {
    jam();
    globalTransporterRegistry.setIOState(hostId, NoHalt);
  }

  //------------------------------------------
  // Also report this event to the Event handler
  //------------------------------------------
  signal->theData[0] = NDB_LE_Connected;
  signal->theData[1] = hostId;
  sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
예제 #29
0
void NodeSystem::removeChild(FUSE::Handle handle, const std::string& name) {
    auto& parentNode = getNodeInfo(handle).node;

    if (parentNode.type() != TYPE_DIRECTORY) {
        throw FUSE::ErrorException(ENOTDIR);
    }

    const auto path = getPath(handle) + name;

    Directory directory(parentNode);

    if (!directory.hasChild(name)) {
        throw FUSE::ErrorException(ENOENT);
    }

    // Remove child.
    directory.removeChild(name);

    // Remove metadata.
    removeAllMetadata(path);

    // Detach open handles.
    detachAllHandles(path);
}
예제 #30
0
void Cmvmi::execOPEN_COMREQ(Signal* signal)
{
  // Connect to the specifed NDB node, only QMGR allowed communication 
  // so far with the node

  const BlockReference userRef = signal->theData[0];
  Uint32 tStartingNode = signal->theData[1];
  Uint32 tData2 = signal->theData[2];
  jamEntry();

  const Uint32 len = signal->getLength();
  if(len == 2)
  {
#ifdef ERROR_INSERT
    if (! ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002)) 
	   && c_error_9000_nodes_mask.get(tStartingNode)))
#endif
    {
      if (globalData.theStartLevel != NodeState::SL_STARTED &&
          (getNodeInfo(tStartingNode).m_type != NodeInfo::DB &&
           getNodeInfo(tStartingNode).m_type != NodeInfo::MGM))
      {
        jam();
        goto done;
      }

      globalTransporterRegistry.do_connect(tStartingNode);
      globalTransporterRegistry.setIOState(tStartingNode, HaltIO);
      
      //-----------------------------------------------------
      // Report that the connection to the node is opened
      //-----------------------------------------------------
      signal->theData[0] = NDB_LE_CommunicationOpened;
      signal->theData[1] = tStartingNode;
      sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
      //-----------------------------------------------------
    }
  } else {
    for(unsigned int i = 1; i < MAX_NODES; i++ ) 
    {
      jam();
      if (i != getOwnNodeId() && getNodeInfo(i).m_type == tData2)
      {
	jam();

#ifdef ERROR_INSERT
	if ((ERROR_INSERTED(9000) || ERROR_INSERTED(9002))
	    && c_error_9000_nodes_mask.get(i))
	  continue;
#endif
	
	globalTransporterRegistry.do_connect(i);
	globalTransporterRegistry.setIOState(i, HaltIO);
	
	signal->theData[0] = NDB_LE_CommunicationOpened;
	signal->theData[1] = i;
	sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
      }
    }
  }
  
done:  
  if (userRef != 0) {
    jam(); 
    signal->theData[0] = tStartingNode;
    signal->theData[1] = tData2;
    sendSignal(userRef, GSN_OPEN_COMCONF, signal, len - 1,JBA);
  }
}