Project

General

Profile

Actions

Bug #47033

closed

Bug #46882: client: mount abort hangs: [volumes INFO mgr_util] aborting connection from cephfs 'cephfs'

client: inode ref leak

Added by Zheng Yan over 3 years ago. Updated over 3 years ago.

Status:
Duplicate
Priority:
High
Assignee:
Category:
-
Target version:
% Done:

0%

Source:
Development
Tags:
Backport:
octopus,nautilus
Regression:
No
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Component(FS):
Client
Labels (FS):
Pull request ID:
Crash signature (v1):
Crash signature (v2):

Description

It can be easily reproduced by following program.

#define _FILE_OFFSET_BITS 64
#include <features.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <cephfs/libcephfs.h>

int main(int argc, char *argv[]) {

        struct ceph_mount_info *cmount = NULL;
        int n = 64;
        bool parent = true;

        if (argc > 2)
                n = atoi(argv[2]);

        while (--n >= 0) {
                pid_t pid = fork();
                if (pid < 0) {
                        printf("fork fail %d\n", pid);
                        exit(-1);
                }
                if (pid == 0) {
                        parent = false;
                        break;
                }
        }
        if (parent) {
                pid_t pid;
                int status;
                while ((pid = wait(&status)) > 0);
                return 0;
        }

        ceph_create(&cmount, "admin");
        ceph_conf_read_file(cmount, "./ceph.conf");
        ceph_mount(cmount, NULL);

        ceph_chdir(cmount, argv[1]);

        char buf[4096];
        sprintf(buf, "dir%d", n);
        int ret = ceph_mkdir(cmount, buf, 0755);
        if (ret < 0 && ret != -EEXIST) {
                printf("ceph_mkdir fail %d\n", ret);
                return 0;
        }

        ceph_chdir(cmount, buf);

        /*
        struct ceph_dir_result *dirp;
        ret = ceph_opendir(cmount, ".", &dirp);
        if (ret < 0) {
                printf("ceph_opendir fail %d\n", ret);
                return 0;
        }

        while (ceph_readdir(cmount, dirp))
                ;

        ceph_closedir(cmount, dirp);
        */

        int count = 0;
        time_t start = time(NULL);
        for (int i = 0; i < 20000; ++i) {
                sprintf(buf, "file%d", i, i);
                int fd = ceph_open(cmount, buf, O_CREAT|O_RDONLY, 0644);
                if (fd < 0) {
                        printf("ceph_open fail %d\n", fd);
                        exit(-1);
                }
                /*
                ret = ceph_fchmod(cmount, fd, 0666);
                if (ret < 0) {
                        printf("ceph_fchmod fail %d\n", ret);
                        exit(-1);
                }
                */

                ceph_close(cmount, fd);
                count++;
                if (time(NULL) > start) {
                        printf("%d\n", count);
                        count = 0;
                        start = time(NULL);
                }
        }
        ceph_unmount(cmount);
        return 0;
}

pre-create testdir at root of cephfs, change mode of testdir to 0777.

repeatedly run './test_create testdir 1' (without removing cleanup data)

last good commit is aef8569b807dc946f7dabc44b20c5d986c44e364. taking client_lock in Client::put_inode does not work

Actions

Also available in: Atom PDF