Exemple #1
0
bool TPath::HasAccess(const TCred &cred, enum Access mask) const {
    struct stat st;
    int mode;

    if (!cred.Uid && !access(c_str(), mask & TPath::RWX))
        return true;

    if (stat(c_str(), &st)) {
        if (!(mask & TPath::P) || errno != ENOENT)
            return false;
        TPath dir = DirName();
        while (stat(dir.c_str(), &st)) {
            if (errno != ENOENT)
                return false;
            if (dir.Path.size() <= 1)
                return false;
            dir = dir.DirName();
        }
    }

    if ((mask & TPath::U) && cred.Uid == st.st_uid)
        return true;

    if (cred.Uid == st.st_uid)
        mode = st.st_mode >> 6;
    else if (cred.IsMemberOf(st.st_gid))
Exemple #2
0
TError TNamespaceFd::Open(TPath path) {
    Close();
    Fd = open(path.c_str(), O_RDONLY | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
    if (Fd < 0)
        return TError(EError::Unknown, errno, "Cannot open " + path.ToString());
    return TError::Success();
}
Exemple #3
0
TError TMount::Find(TPath path, const TPath mounts) {

    path = path.NormalPath();
    auto device = path.GetDev();
    if (!device)
        return TError(EError::Unknown, "device not found: " + path.ToString() + ")");

    FILE* f = setmntent(mounts.c_str(), "r");
    if (!f)
        return TError(EError::Unknown, errno, "setmntent(" + mounts.ToString() + ")");

    struct mntent* m, mntbuf;
    TScopedMem buf(4096);
    TError error(EError::Unknown, "mountpoint not found: " + path.ToString() + ")");

    while ((m = getmntent_r(f, &mntbuf, (char *)buf.GetData(), buf.GetSize()))) {

        TPath source(m->mnt_fsname);
        TPath target(m->mnt_dir);

        if (target.InnerPath(path).IsEmpty() ||
                source.GetBlockDev() != device)
            continue;

        Source = source;
        Target = target;
        Type = m->mnt_type;
        Data.clear();
        error = SplitString(m->mnt_opts, ',', Data);
        break;
    }
    endmntent(f);

    return error;
}
Exemple #4
0
TError TMount::Snapshot(std::vector<std::shared_ptr<TMount>> &result, const TPath mounts) {
    FILE* f = setmntent(mounts.c_str(), "r");
    if (!f)
        return TError(EError::Unknown, errno, "setmntent(" + mounts.ToString() + ")");

    struct mntent* m, mntbuf;
    TScopedMem buf(4096);
    while ((m = getmntent_r(f, &mntbuf, (char *)buf.GetData(), buf.GetSize()))) {
        vector<string> flags;
        TError error = SplitString(m->mnt_opts, ',', flags);
        if (error) {
            endmntent(f);
            return error;
        }
        result.push_back(std::make_shared<TMount>(m->mnt_fsname, m->mnt_dir, m->mnt_type, flags));
    }
    endmntent(f);
    return TError::Success();
}
Exemple #5
0
TError SetupLoopDevice(TPath image, int &dev)
{
    static std::mutex BigLoopLock;
    int control_fd, image_fd, loop_nr, loop_fd;
    struct loop_info64 info;
    std::string loop;
    int retry = 10;
    TError error;

    image_fd = open(image.c_str(), O_RDWR | O_CLOEXEC);
    if (image_fd < 0) {
        error = TError(EError::Unknown, errno, "open(" + image.ToString() + ")");
        goto err_image;
    }

    control_fd = open("/dev/loop-control", O_RDWR | O_CLOEXEC);
    if (control_fd < 0) {
        error = TError(EError::Unknown, errno, "open(/dev/loop-control)");
        goto err_control;
    }

    BigLoopLock.lock();

again:
    loop_nr = ioctl(control_fd, LOOP_CTL_GET_FREE);
    if (loop_nr < 0) {
        error = TError(EError::Unknown, errno, "ioctl(LOOP_CTL_GET_FREE)");
        goto err_get_free;
    }

    loop = "/dev/loop" + std::to_string(loop_nr);
    loop_fd = open(loop.c_str(), O_RDWR | O_CLOEXEC);
    if (loop_fd < 0) {
        error = TError(EError::Unknown, errno, "open(" + loop + ")");
        goto err_loop_open;
    }

    if (ioctl(loop_fd, LOOP_SET_FD, image_fd) < 0) {
        error = TError(EError::Unknown, errno, "ioctl(LOOP_SET_FD)");
        if (errno == EBUSY) {
            if (!ioctl(loop_fd, LOOP_GET_STATUS64, &info) || errno == ENXIO) {
                if (--retry > 0) {
                    close(loop_fd);
                    goto again;
                }
            }
        }
        goto err_set_fd;
    }

    memset(&info, 0, sizeof(info));
    strncpy((char *)info.lo_file_name, image.c_str(), LO_NAME_SIZE);

    if (ioctl(loop_fd, LOOP_SET_STATUS64, &info) < 0) {
        error = TError(EError::Unknown, errno, "ioctl(LOOP_SET_STATUS64)");
        ioctl(loop_fd, LOOP_CLR_FD, 0);
        goto err_set_status;
    }

    dev = loop_nr;
    error = TError::Success();
err_set_status:
err_set_fd:
    close(loop_fd);
err_loop_open:
err_get_free:
    BigLoopLock.unlock();
    close(control_fd);
err_control:
    close(image_fd);
err_image:
    return error;
}
Exemple #6
0
TError TMount::Remount(TPath path, unsigned long flags) {
    if (mount(NULL, path.c_str(), NULL, flags, NULL))
        return TError(EError::Unknown, errno, "mount(NULL, " + path.ToString() + ", NULL, " + std::to_string(flags) + ", NULL)");
    return TError::Success();
}