示例#1
0
文件: holder.cpp 项目: darkk/porto
TError TContainerHolder::Restore(TScopedLock &holder_lock, const std::string &name,
                                 const kv::TNode &node) {
    if (name == ROOT_CONTAINER || name == PORTO_ROOT_CONTAINER)
        return TError::Success();

    L_ACT() << "Restore container " << name << " (" << node.ShortDebugString() << ")" << std::endl;

    auto parent = GetParent(name);
    if (!parent)
        return TError(EError::InvalidValue, "invalid parent container");

    int id = 0;
    TError error = RestoreId(node, id);
    if (error)
        return error;

    if (!id)
        return TError(EError::Unknown, "Couldn't restore container id");

    auto c = std::make_shared<TContainer>(shared_from_this(), Storage, name, parent, id);
    error = c->Restore(holder_lock, node);
    if (error) {
        L_ERR() << "Can't restore container " << name << ": " << error << std::endl;
        return error;
    }

    Containers[name] = c;
    Statistics->Created++;
    return TError::Success();
}
示例#2
0
TError TClient::ComposeRelativeName(const TContainer &target,
                                    std::string &relative_name) const {
    std::string name = target.GetName();
    auto base = ClientContainer.lock();
    if (!base)
        return TError(EError::ContainerDoesNotExist, "Cannot find client container");
    std::string ns = base->GetPortoNamespace();

    if (target.IsRoot()) {
        relative_name = ROOT_CONTAINER;
        return TError::Success();
    }

    if (ns == "") {
        relative_name = name;
        return TError::Success();
    }

    if (name.length() <= ns.length() || name.compare(0, ns.length(), ns) != 0)
        return TError(EError::ContainerDoesNotExist,
                      "Cannot access container " + name + " from namespace " + ns);

    relative_name = name.substr(ns.length());
    return TError::Success();
}
示例#3
0
TError TNlLink::AddDirectRoute(const TNlAddr &addr) {
    struct rtnl_route *route;
    struct rtnl_nexthop *nh;
    int ret;

    route = rtnl_route_alloc();
    if (!route)
        return TError(EError::Unknown, "Cannot allocate route");

    ret = rtnl_route_set_dst(route, addr.Addr);
    if (ret < 0) {
        rtnl_route_put(route);
        return Error(ret, "Cannot set route destination");
    }

    nh = rtnl_route_nh_alloc();
    if (!route) {
        rtnl_route_put(route);
        return TError(EError::Unknown, "Cannot allocate next hop");
    }

    rtnl_route_nh_set_ifindex(nh, GetIndex());
    rtnl_route_add_nexthop(route, nh);

    Dump("add", route);
    ret = rtnl_route_add(GetSock(), route, NLM_F_CREATE | NLM_F_REPLACE);
    rtnl_route_put(route);
    if (ret < 0)
        return Error(ret, "Cannot add direct route");

    return TError::Success();
}
示例#4
0
TError TNlHtb::Create(const TNlLink &link, uint32_t defaultClass) {
    TError error = TError::Success();
    int ret;
    struct rtnl_qdisc *qdisc;

    qdisc = rtnl_qdisc_alloc();
    if (!qdisc)
        return TError(EError::Unknown, std::string("Unable to allocate qdisc object"));

    rtnl_tc_set_ifindex(TC_CAST(qdisc), link.GetIndex());
    rtnl_tc_set_parent(TC_CAST(qdisc), Parent);
    rtnl_tc_set_handle(TC_CAST(qdisc), Handle);

    ret = rtnl_tc_set_kind(TC_CAST(qdisc), "htb");
    if (ret < 0) {
        error = TError(EError::Unknown, std::string("Unable to set qdisc type: ") + nl_geterror(ret));
        goto free_qdisc;
    }

    rtnl_htb_set_defcls(qdisc, TC_H_MIN(defaultClass));
    rtnl_htb_set_rate2quantum(qdisc, 10);

    link.Dump("add", qdisc);

    ret = rtnl_qdisc_add(link.GetSock(), qdisc, NLM_F_CREATE);
    if (ret < 0)
        error = TError(EError::Unknown, std::string("Unable to add qdisc: ") + nl_geterror(ret));

free_qdisc:
    rtnl_qdisc_put(qdisc);

    return error;
}
示例#5
0
TError TNlCgFilter::Remove(const TNlLink &link) {
    TError error = TError::Success();
    struct rtnl_cls *cls;
    int ret;

    cls = rtnl_cls_alloc();
    if (!cls)
        return TError(EError::Unknown, std::string("Unable to allocate filter object"));

    rtnl_tc_set_ifindex(TC_CAST(cls), link.GetIndex());

    ret = rtnl_tc_set_kind(TC_CAST(cls), FilterType);
    if (ret < 0) {
        error = TError(EError::Unknown, std::string("Unable to set filter type: ") + nl_geterror(ret));
        goto free_cls;
    }

    rtnl_cls_set_prio(cls, FilterPrio);
    rtnl_cls_set_protocol(cls, 0);
    rtnl_tc_set_parent(TC_CAST(cls), Parent);

    link.Dump("remove", cls);

    ret = rtnl_cls_delete(link.GetSock(), cls, 0);
    if (ret < 0)
        error = TError(EError::Unknown, std::string("Unable to remove filter: ") + nl_geterror(ret));

free_cls:
    rtnl_cls_put(cls);

    return error;
}
示例#6
0
TError TClient::SendResponse(bool first) {
    TScopedLock lock(Mutex);

    if (Fd < 0)
        return TError::Success(); /* Connection closed */

    ssize_t len = send(Fd, &Buffer[Offset], Length - Offset, MSG_DONTWAIT);
    if (len > 0)
        Offset += len;
    else if (len == 0) {
        if (!first)
            return TError(EError::Unknown, "send return zero");
    } else if (errno != EAGAIN && errno != EWOULDBLOCK)
        return TError(EError::Unknown, errno, "send response failed");

    if (Offset >= Length) {
        Length = Offset = 0;
        Processing = false;
        return EpollLoop->StartInput(Fd);
    }

    if (first)
        return EpollLoop->StartOutput(Fd);

    return TError::Success();
}
示例#7
0
TError TTclass::Create() {
    TError firstError = TError::Success();

    for (auto &link : Net->GetLinks()) {
        auto alias = link->GetAlias();

        if (Prio.find(alias) == Prio.end())
            return TError(EError::Unknown, "Can't find prio for link " + alias);
        else if (Rate.find(alias) == Rate.end())
            return TError(EError::Unknown, "Can't find rate for link " + alias);
        else if (Ceil.find(alias) == Ceil.end())
            return TError(EError::Unknown, "Can't find ceil for link " + alias);

        TNlClass tclass(link, GetParent(), Handle);
        if (tclass.Exists()) {
            if (!tclass.Valid(Prio[alias], Rate[alias], Ceil[alias]))
                (void)tclass.Remove();
            else
                continue;
        }

        TError error = tclass.Create(Prio[alias], Rate[alias], Ceil[alias]);
        if (!firstError)
            firstError = error;
    }

    if (firstError)
        return firstError;

    return TError::Success();
}
示例#8
0
文件: client.cpp 项目: noxiouz/porto
TError TClient::IdentifyClient(TContainerHolder &holder, bool initial) {
    std::shared_ptr<TContainer> ct;
    struct ucred cr;
    socklen_t len = sizeof(cr);
    TError error;

    if (getsockopt(Fd, SOL_SOCKET, SO_PEERCRED, &cr, &len))
        return TError(EError::Unknown, errno, "Cannot identify client: getsockopt() failed");

    /* check that request from the same pid and container is still here */
    if (!initial && Pid == cr.pid && TaskCred.Uid == cr.uid &&
            TaskCred.Gid == cr.gid && !ClientContainer.expired())
        return TError::Success();

    TaskCred.Uid = cr.uid;
    TaskCred.Gid = cr.gid;
    Pid = cr.pid;

    error = holder.FindTaskContainer(Pid, ct);
    if (error && error.GetErrno() != ENOENT)
        L_WRN() << "Cannot identify container of pid " << Pid
                << " : " << error << std::endl;
    if (error)
        return error;

    if (!ct->IsPortoEnabled())
        return TError(EError::Permission,
                      "Porto disabled in container " + ct->GetName());

    ClientContainer = ct;

    error = TPath("/proc/" + std::to_string(Pid) + "/comm").ReadAll(Comm, 64);
    if (error)
        Comm = "<unknown process>";
    else
        Comm.resize(Comm.length() - 1); /* cut \n at the end */

    if (ct->IsRoot()) {
        Cred.Uid = cr.uid;
        Cred.Gid = cr.gid;
        error = LoadGroups();
        if (error && error.GetErrno() != ENOENT)
            L_WRN() << "Cannot load supplementary group list" << Pid
                    << " : " << error << std::endl;
    } else {
        /* requests from containers are executed in behalf of their owners */
        Cred = ct->OwnerCred;
    }

    ReadOnlyAccess = !Cred.IsPortoUser();

    return TError::Success();
}
示例#9
0
文件: unix.cpp 项目: direvius/porto
TError GetTaskParent(pid_t pid, pid_t &parent_pid) {
    std::string path = "/proc/" + std::to_string(pid) + "/stat";
    int res, ppid;
    FILE *file;

    file = fopen(path.c_str(), "r");
    if (!file)
        return TError(EError::Unknown, errno, "fopen(" + path + ")");
    res = fscanf(file, "%*d (%*[^)]) %*c %d", &ppid);
    fclose(file);
    if (res != 1)
        return TError(EError::Unknown, errno, "Cannot parse " + path);
    parent_pid = ppid;
    return TError::Success();
}
示例#10
0
文件: holder.cpp 项目: darkk/porto
TError TContainerHolder::CreateRoot(TScopedLock &holder_lock) {
    std::shared_ptr<TContainer> container;
    TError error;

    error = Create(holder_lock, ROOT_CONTAINER, TCred(0, 0), container);
    if (error)
        return error;

    if (container->GetId() != ROOT_CONTAINER_ID)
        return TError(EError::Unknown, "Unexpected root container id " + std::to_string(container->GetId()));

    error = IdMap.GetAt(DEFAULT_TC_MINOR);
    if (error)
        return error;

    error = container->Prop->Set<bool>(P_ISOLATE, false);
    if (error)
        return error;

    error = container->Prop->Set<std::vector<std::string>>(P_NET, { "host" });
    if (error)
        return error;

    error = container->Start(nullptr, true);
    if (error)
        return error;

    return TError::Success();
}
示例#11
0
文件: cgroup.cpp 项目: noxiouz/porto
TError TCgroup::Remove() const {
    struct stat st;
    TError error;

    if (Secondary())
        return TError(EError::Unknown, "Cannot create secondary cgroup " + Type());

    L_ACT() << "Remove cgroup " << *this << std::endl;
    error = Path().Rmdir();

    /* workaround for bad synchronization */
    if (error && error.GetErrno() == EBUSY &&
            !Path().StatStrict(st) && st.st_nlink == 2) {
        for (int i = 0; i < 100; i++) {
            usleep(config().daemon().cgroup_remove_timeout_s() * 10000);
            error = Path().Rmdir();
            if (!error || error.GetErrno() != EBUSY)
                break;
        }
    }

    if (error && (error.GetErrno() != ENOENT || Exists()))
        L_ERR() << "Cannot remove cgroup " << *this << " : " << error << std::endl;

    return error;
}
示例#12
0
TError TNlLink::AddAddress(const TNlAddr &addr) {
    struct rtnl_addr *a = rtnl_addr_alloc();
    if (!a)
        return TError(EError::Unknown, "Cannot allocate address");

    rtnl_addr_set_link(a, Link);
    rtnl_addr_set_family(a, nl_addr_get_family(addr.Addr));
    rtnl_addr_set_flags(a, IFA_F_NODAD);

    int ret = rtnl_addr_set_local(a, addr.Addr);
    if (ret < 0) {
        rtnl_addr_put(a);
        return Error(ret, "Cannot set local address");
    }

    ret = rtnl_addr_add(GetSock(), a, 0);
    if (ret < 0) {
        rtnl_addr_put(a);
        return Error(ret, "Cannot add address");
    }

    rtnl_addr_put(a);

    return TError::Success();
}
示例#13
0
文件: holder.cpp 项目: darkk/porto
TError TContainerHolder::CreatePortoRoot(TScopedLock &holder_lock) {
    std::shared_ptr<TContainer> container;
    TError error = Create(holder_lock, PORTO_ROOT_CONTAINER, TCred(0, 0), container);
    if (error)
        return error;

    if (container->GetId() != PORTO_ROOT_CONTAINER_ID)
        return TError(EError::Unknown, "Unexpected /porto container id " + std::to_string(container->GetId()));

    error = container->Prop->Set<bool>(P_ISOLATE, false);
    if (error)
        return error;

    error = container->Start(nullptr, true);
    if (error)
        return error;

    ScheduleLogRotatation();

    Statistics->Created = 0;
    Statistics->RestoreFailed = 0;
    Statistics->RemoveDead = 0;
    Statistics->Rotated = 0;
    Statistics->Started = 0;

    return TError::Success();
}
示例#14
0
TError TNl::ProxyNeighbour(int ifindex, const TNlAddr &addr, bool add) {
    struct rtnl_neigh *neigh;
    int ret;

    neigh = rtnl_neigh_alloc();
    if (!neigh)
        return TError(EError::Unknown, "Cannot allocate neighbour");

    ret = rtnl_neigh_set_dst(neigh, addr.Addr);
    if (ret) {
        rtnl_neigh_put(neigh);
        return Error(ret, "Cannot set neighbour dst");
    }

    rtnl_neigh_set_flags(neigh, NTF_PROXY);
    rtnl_neigh_set_state(neigh, NUD_PERMANENT);
    rtnl_neigh_set_ifindex(neigh, ifindex);

    if (add) {
        Dump("add", neigh);
        ret = rtnl_neigh_add(Sock, neigh, NLM_F_CREATE | NLM_F_REPLACE);
    } else {
        Dump("del", neigh);
        ret = rtnl_neigh_delete(Sock, neigh, 0);

        if (ret == -NLE_OBJ_NOTFOUND)
            ret = 0;
    }
    rtnl_neigh_put(neigh);
    if (ret)
        return Error(ret, "Cannot modify neighbour for l3 network");

    return TError::Success();
}
示例#15
0
void CGrottoGame::SetupGame(tstring sType)
{
	if (sType == "level")
	{
		CGrottoPlayer* pPlayer = GameServer()->Create<CGrottoPlayer>("CGrottoPlayer");
		Game()->AddPlayer(pPlayer);

		CPlayerCharacter* pCharacter = GameServer()->Create<CPlayerCharacter>("CPlayerCharacter");
		pCharacter->SetGlobalOrigin(Vector(0, 0, 0));
		pPlayer->SetCharacter(pCharacter);

		GameServer()->LoadLevel(CVar::GetCVarValue("game_level"));

		pCharacter->MoveToPlayerStart();

		Application()->SetMouseCursorEnabled(false);
	}
	else if (sType == "menu")
	{
		Application()->SetMouseCursorEnabled(true);
	}
	else
	{
		TError("Unrecognized game type: " + sType + "\n");
	}
}
示例#16
0
TError TNlClass::Load(const TNl &nl) {
    struct nl_cache *cache;
    struct rtnl_class *tclass;

    int ret = rtnl_class_alloc_cache(nl.GetSock(), Index, &cache);
    if (ret < 0)
            return nl.Error(ret, "Cannot allocate class cache");

    tclass = rtnl_class_get(cache, Index, Handle);
    if (!tclass) {
        nl_cache_free(cache);
        return TError(EError::Unknown, "Can't find tc class");
    }

    Kind = rtnl_tc_get_kind(TC_CAST(tclass));

    if (Kind == "htb") {
        Prio = rtnl_htb_get_prio(tclass);
        Rate = rtnl_htb_get_rate(tclass);
        Ceil = rtnl_htb_get_ceil(tclass);
    }

    if (Kind == "hfsc") {
        struct tc_service_curve sc;
        if (!rtnl_class_hfsc_get_fsc(tclass, &sc))
            Rate = sc.m2;
        if (!rtnl_class_hfsc_get_usc(tclass, &sc))
            Ceil = sc.m2;
    }

    rtnl_class_put(tclass);
    nl_cache_free(cache);

    return TError::Success();
}
示例#17
0
文件: cgroup.cpp 项目: noxiouz/porto
TError TCgroup::GetPids(const std::string &knob, std::vector<pid_t> &pids) const {
    FILE *file;
    int pid;

    if (!Subsystem)
        return TError(EError::Unknown, "Cannot get from null cgroup");

    file = fopen(Knob(knob).c_str(), "r");;
    if (!file)
        return TError(EError::Unknown, errno, "Cannot open knob " + knob);
    while (fscanf(file, "%d", &pid) == 1)
        pids.push_back(pid);
    fclose(file);

    return TError::Success();
}
示例#18
0
文件: holder.cpp 项目: darkk/porto
TError TContainerHolder::Get(const std::string &name, std::shared_ptr<TContainer> &c) {
    if (Containers.find(name) == Containers.end())
        return TError(EError::ContainerDoesNotExist, "container " + name + " doesn't exist");

    c = Containers[name];
    return TError::Success();
}
示例#19
0
size_t CToyUtil::AddSceneArea(const tstring& sFileName)
{
	CToy* pArea = new CToy();
	bool bRead = CToyUtil::Read(GetGameDirectory() + T_DIR_SEP + sFileName, pArea);

	if (!bRead)
	{
		delete pArea;

		TAssert(bRead);
		TError("Couldn't find scene area " + sFileName + "\n");

		return ~0;
	}

	CSceneArea& oSceneArea = m_asSceneAreas.push_back();

	oSceneArea.m_sFileName = sFileName;
	oSceneArea.m_aabbArea = pArea->GetVisBounds();

	// I'm visible to myself.
	oSceneArea.m_aiNeighboringAreas.push_back(m_asSceneAreas.size()-1);

	delete pArea;

	return m_asSceneAreas.size()-1;
}
示例#20
0
文件: unix.cpp 项目: direvius/porto
TError DropBoundedCap(int cap) {
    if (prctl(PR_CAPBSET_DROP, cap, 0, 0, 0) < 0)
        return TError(EError::Unknown, errno,
                      "prctl(PR_CAPBSET_DROP, " + std::to_string(cap) + ")");

    return TError::Success();
}
示例#21
0
文件: unix.cpp 项目: direvius/porto
TError SetHostName(const std::string &name) {
    int ret = sethostname(name.c_str(), name.length());
    if (ret < 0)
        return TError(EError::Unknown, errno, "sethostname(" + name + ")");

    return TError::Success();
}
示例#22
0
//---------------------------------------------------------------------------
void __fastcall TDialogToolUDPSender::ButtonSendClick(TObject *Sender)
{
/* */
  try {
    TUDP UDP;
    if (!UDP.Connect(EditIP->Text, TUtils::AToI(EditPort->Text), TUDP::Server))
      throw TError("Can't do UDP.Connect");
    UDP.Send(EditContens->Text);
  }
  catch (TError &E)
  {
    E.Show();
  }
/**/
/**/
  DynamicArray<unsigned char> Data;
  Data.Length = EditContens->Text.Length();
  for (int I = 0; I < Data.Length; I++) Data[I] = EditContens->Text[I + 1];
  IdUDPClient->Active = true;
  //IdUDPClient->SendBuffer(EditIP->Text, TUtils::AToI(EditPort->Text), Data);
  IdUDPClient->Host = EditIP->Text;
  IdUDPClient->Port = TUtils::AToI(EditPort->Text);
  IdUDPClient->SendBuffer(Data);
  //IdUDPClient->Active = false;
/**/
}
示例#23
0
文件: cgroup.cpp 项目: noxiouz/porto
TError TSubsystem::TaskCgroup(pid_t pid, TCgroup &cgroup) const {
    FILE *file = fopen(("/proc/" + std::to_string(pid) + "/cgroup").c_str(), "r");

    if (file) {
        int id;

        while (fscanf(file, "%d:", &id) == 1) {
            bool found = false;
            char *ss, *cg;

            while (fscanf(file, "%m[^:,],", &ss) == 1) {
                if (std::string(ss) == Type)
                    found = true;
                free(ss);
            }

            if (fscanf(file, ":%ms\n", &cg) == 1) {
                if (found) {
                    cgroup.Subsystem = this;
                    cgroup.Name = std::string(cg);
                    free(cg);
                    fclose(file);
                    return TError::Success();
                }
                free(cg);
            }
        }
        fclose(file);
    }

    return TError(EError::Unknown, errno, "Cannot find " + Type +
                    " cgroup for process " + std::to_string(pid));
}
示例#24
0
TError TClient::AcceptConnection(TContext &context, int listenFd) {
    struct sockaddr_un peer_addr;
    socklen_t peer_addr_size;
    TError error;

    peer_addr_size = sizeof(struct sockaddr_un);
    Fd = accept4(listenFd, (struct sockaddr *) &peer_addr,
                 &peer_addr_size, SOCK_NONBLOCK | SOCK_CLOEXEC);
    if (Fd < 0) {
        error = TError(EError::Unknown, errno, "accept4()");
        if (error.GetErrno() != EAGAIN)
            L_WRN() << "Cannot accept client: " << error << std::endl;
        return error;
    }

    error = IdentifyClient(*context.Cholder, true);
    if (error) {
        close(Fd);
        Fd = -1;
        return error;
    }

    if (Verbose)
        L() << "Client connected: " << *this << std::endl;

    return TError::Success();
}
示例#25
0
TError TNlLink::AddIpVlan(const std::string &master,
                          const std::string &mode, int mtu) {
#ifdef IFLA_IPVLAN_MAX
    return AddXVlan("ipvlan", master, ipvlanMode.at(mode), "", mtu);
#else
    return TError(EError::NotSupported, "Porto is not compiled with IP VLAN support");
#endif
}
示例#26
0
文件: holder.cpp 项目: darkk/porto
TError TContainerHolder::Create(TScopedLock &holder_lock, const std::string &name, const TCred &cred, std::shared_ptr<TContainer> &container) {
    TError error;

    error = ValidName(name);
    if (error)
        return error;

    if (Containers.find(name) != Containers.end())
        return TError(EError::ContainerAlreadyExists, "container " + name + " already exists");

    if (Containers.size() + 1 > config().container().max_total())
        return TError(EError::ResourceNotAvailable, "number of created containers exceeds limit");

    auto parent = GetParent(name);
    if (!parent && name != ROOT_CONTAINER)
        return TError(EError::InvalidValue, "invalid parent container");

    if (parent && parent->GetLevel() == CONTAINER_LEVEL_MAX)
        return TError(EError::InvalidValue, "You shall not go deeper!");

    if (parent && !parent->IsRoot() && !parent->IsPortoRoot()) {
        error = parent->CheckPermission(cred);
        if (error)
            return error;
    }

    int id;
    error = IdMap.Get(id);
    if (error)
        return error;

    auto c = std::make_shared<TContainer>(shared_from_this(), Storage, name, parent, id);
    error = c->Create(cred);
    if (error)
        return error;

    Containers[name] = c;
    Statistics->Created++;

    if (parent)
        parent->AddChild(c);

    container = c;

    return TError::Success();
}
示例#27
0
文件: client.cpp 项目: direvius/porto
TError TClient::ReadRequest(rpc::TContainerRequest &request) {
    if (config().daemon().blocking_read()) {
        InterruptibleInputStream InputStream(Fd);
        ReadDelimitedFrom(&InputStream, &request);
        return TError::Success();
    }

    if (Offset >= Buffer.size())
        Buffer.resize(Offset + 4096);

    ssize_t len = recv(Fd, &Buffer[Offset], Buffer.size() - Offset, MSG_DONTWAIT);
    if (len > 0)
        Offset += len;
    else if (len == 0 || (errno != EAGAIN && errno != EWOULDBLOCK))
        return TError(EError::Unknown, len ? errno : EIO, "recv request failed");

    if (Length && Offset < Length)
        return TError::Queued();

    google::protobuf::io::CodedInputStream input(&Buffer[0], Offset);

    uint32_t length;
    if (!input.ReadVarint32(&length))
        return TError::Queued();

    if (!Length) {
        if (length > config().daemon().max_msg_len())
            return TError(EError::Unknown, "oversized request: " + std::to_string(length));

        Length = length + google::protobuf::io::CodedOutputStream::VarintSize32(length);
        if (Buffer.size() < Length)
            Buffer.resize(Length);

        if (Offset < Length)
            return TError::Queued();
    }

    if (!request.ParseFromCodedStream(&input))
        return TError(EError::Unknown, "cannot parse request");

    if (Offset > Length)
        return TError(EError::Unknown, "garbage after request");

    return EpollLoop->StopInput(Fd);
}
示例#28
0
TError TClient::IdentifyClient(TContainerHolder &holder, bool initial) {
    struct ucred cr;
    socklen_t len = sizeof(cr);
    TError error;

    if (getsockopt(Fd, SOL_SOCKET, SO_PEERCRED, &cr, &len))
        return TError(EError::Unknown, errno, "Cannot identify client: getsockopt() failed");

    if (!initial && Pid == cr.pid && Cred.Uid == cr.uid && Cred.Gid == cr.gid &&
            !ClientContainer.expired())
        return TError::Success();

    Cred.Uid = cr.uid;
    Cred.Gid = cr.gid;
    Pid = cr.pid;

    error = TPath("/proc/" + std::to_string(Pid) + "/comm").ReadAll(Comm, 64);
    if (error)
        Comm = "<unknown process>";
    else
        Comm.resize(Comm.length() - 1); /* cut \n at the end */

    error = LoadGroups();
    if (error && error.GetErrno() != ENOENT)
        L_WRN() << "Cannot load supplementary group list" << Pid
                << " : " << error << std::endl;

    ReadOnlyAccess = !Cred.IsPortoUser();

    std::shared_ptr<TContainer> container;
    error = holder.FindTaskContainer(Pid, container);
    if (error && error.GetErrno() != ENOENT)
        L_WRN() << "Cannot identify container of pid " << Pid
                << " : " << error << std::endl;
    if (error)
        return error;

    if (!container->Prop->Get<bool>(P_ENABLE_PORTO))
        return TError(EError::Permission, "Porto disabled in container " + container->GetName());

    ClientContainer = container;
    return TError::Success();
}
示例#29
0
文件: cgroup.cpp 项目: noxiouz/porto
TError TCgroup::GetUintMap(const std::string &knob, TUintMap &value) const {
    if (!Subsystem)
        return TError(EError::Unknown, "Cannot get from null cgroup");

    FILE *file = fopen(Knob(knob).c_str(), "r");
    char *key;
    unsigned long long val;

    if (!file)
        return TError(EError::Unknown, errno, "Cannot open knob " + knob);

    while (fscanf(file, "%ms %llu\n", &key, &val) == 2) {
        value[std::string(key)] = val;
        free(key);
    }

    fclose(file);
    return TError::Success();
}
TInt CDatabaseManagerServerSession::SetInterfaceDefaultL(const RMessage2& aMessage)
    {
    TInt ret;
    HBufC* serviceNameBuf = HBufC::New(aMessage.GetDesLength(0));
    HBufC* interfaceNameBuf = HBufC::New(aMessage.GetDesLength(1));
    if (!serviceNameBuf || !interfaceNameBuf)
        return KErrNoMemory;

    TPtr ptrToBuf(serviceNameBuf->Des());
    TPtr ptrToBuf2(interfaceNameBuf->Des());
    
    TRAP(ret, aMessage.ReadL(0, ptrToBuf));
    TRAPD(ret2, aMessage.ReadL(1, ptrToBuf2));
    if (ret != KErrNone || ret2 != KErrNone)
        {
        iDb->lastError().setError(DBError::UnknownError);
        aMessage.Write(2, LastErrorCode());
        delete serviceNameBuf;
        delete interfaceNameBuf;
        return (ret == KErrNone) ? ret2 : ret;
        }

    QString serviceName = QString::fromUtf16(ptrToBuf.Ptr(), ptrToBuf.Length());
    QString interfaceName = QString::fromUtf16(ptrToBuf2.Ptr(), ptrToBuf2.Length());
    
    QList<QServiceInterfaceDescriptor> descriptors;
    QServiceFilter filter;
    filter.setServiceName(serviceName);
    filter.setInterface(interfaceName);
    // Nothing should be returned, because we are checking on nonexistent service
    descriptors = iDb->getInterfaces(filter);

    //find the descriptor with the latest version
    int latestIndex = 0;
        for (int i = 1; i < descriptors.count(); ++i) {
            if (lessThan(descriptors[latestIndex], descriptors[i]))
                latestIndex = i;
    }

    if (!descriptors.isEmpty()) {
        iDb->setInterfaceDefault(descriptors[latestIndex]);     
    }
    else {
        aMessage.Write(2, TError(DBError::NotFound));
        delete serviceNameBuf;
        delete interfaceNameBuf;
        return KErrNotFound;
    }

    aMessage.Write(2, LastErrorCode());
    delete serviceNameBuf;
    delete interfaceNameBuf;
    
    return ret;
    }