+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include "common/errno.h"
-#include "include/cephfs/libcephfs.h"
-#include <stdlib.h>
-
-#include <errno.h>
-#include <dirent.h>
-#include <iostream>
-#include <fcntl.h>
-#include <sys/xattr.h>
-#include <string.h>
-
-using std::cout;
-using std::cerr;
-
-int main(int argc, const char **argv)
-{
- struct ceph_mount_info *cmount;
- cout << "calling ceph_create..." << std::endl;
- int my_fd;
- int ret = ceph_create(&cmount, NULL);
- if (ret) {
- cerr << "ceph_create failed with error: " << ret << std::endl;
- return 1;
- }
- cout << "calling ceph_conf_read_file..." << ret << std::endl;
- ceph_conf_read_file(cmount, NULL);
- cout << "calling ceph_conf_parse_argv..." << ret << std::endl;
- ceph_conf_parse_argv(cmount, argc, argv);
-
- char buf[128];
- cout << "calling ceph_conf_get..." << ret << std::endl;
- ret = ceph_conf_get(cmount, "log file", buf, sizeof(buf));
- if (ret) {
- cerr << "ceph_conf_get(\"log file\") failed with error " << ret << std::endl;
- }
- else {
- cout << "log_file = \"" << buf << "\"" << std::endl;
- }
-
- ret = ceph_mount(cmount, NULL);
- if (ret) {
- cerr << "ceph_mount error: " << ret << std::endl;
- return 1;
- }
- cout << "Successfully mounted Ceph!" << std::endl;
-
- // what if foo is already there???
- struct ceph_dir_result *foo_dir = NULL;
- ret = ceph_opendir(cmount, "foo", &foo_dir);
- if (ret != -ENOENT) {
- cerr << "ceph_opendir error: unexpected result from trying to open foo: "
- << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_opendir: success, foo does not exist" << std::endl;
- }
-
- // Can't close a dir that is not open!
- //ret = ceph_closedir(cmount, foo_dir);
- //if (ret == 0) {
- // cerr << "ceph_closedir success" << std::endl;
- //} else {
- // cerr << "ceph_closedir error: " << cpp_strerror(ret) << std::endl;
- //}
- //
- ret = ceph_mkdir(cmount, "foo", 0777);
- if (ret) {
- cerr << "ceph_mkdir error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_mkdir: success" << std::endl;
- }
-
- struct stat stbuf;
- ret = ceph_lstat(cmount, "foo", &stbuf);
- if (ret) {
- cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_lstat: success" << std::endl;
- }
-
- if (!S_ISDIR(stbuf.st_mode)) {
- cerr << "ceph_lstat(foo): foo is not a directory? st_mode = "
- << stbuf.st_mode << std::endl;
- return 1;
- } else {
- cout << "ceph_lstat: mode success" << std::endl;
- }
-
- ret = ceph_rmdir(cmount, "foo");
- if (ret) {
- cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_rmdir: success" << std::endl;
- }
-
- ret = ceph_mkdirs(cmount, "foo/bar/baz", 0777);
- if (ret) {
- cerr << "ceph_mkdirs error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_mkdirs: success" << std::endl;
- }
-
- // Should test .. as well!
-
- cout << "testing chdir on foo/bar/baz";
- ret = ceph_chdir(cmount, "foo/bar/baz");
- if (ret) {
- cerr << ": failed: " << cpp_strerror(ret) << std::endl;
- return 1;
- }
-
- cout << " success!" << std::endl;
-
- // Now, try absolute
- cout << "testing chdir to /foo/bar";
- ret = ceph_chdir(cmount, "/foo/bar");
- if (ret) {
- cerr << ": failed: " << cpp_strerror(ret) << std::endl;
- return 1;
- }
-
- cout << " success!" << std::endl;
-
- // Now, back to the top
- cout << "testing chdir to /";
- ret = ceph_chdir(cmount, "/");
- if (ret) {
- cerr << ": failed: " << cpp_strerror(ret) << std::endl;
- return 1;
- }
-
- cout << "success!" << std::endl;
-
- ret = ceph_rmdir(cmount, "foo/bar/baz");
- if (ret) {
- cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_rmdir: success" << std::endl;
- }
- ret = ceph_rmdir(cmount, "foo/bar");
- if (ret) {
- cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_rmdir: success" << std::endl;
- }
- ret = ceph_rmdir(cmount, "foo");
- if (ret) {
- cerr << "ceph_rmdir error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_rmdir: success" << std::endl;
- }
- my_fd = ret = ceph_open(cmount, "barfile", O_CREAT, 0666);
- if (ret < 0) {
- cerr << "ceph_open O_CREAT error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_open: success" << std::endl;
- }
- ret = ceph_setxattr(cmount, "barfile", "user.testxattr", (void *) "AYBABTU", 7, XATTR_CREATE);
- if (ret < 0) {
- cerr << "ceph_setxattr error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_setxattr: success" << std::endl;
- }
- char *outlist;
- outlist = (char *) malloc(256);
- ret = ceph_listxattr(cmount, "barfile", outlist, 0);
- free(outlist);
- if (ret < 1) {
- cerr << "ceph_listxattr error (a): should have returned > 0" << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_listxattr: success" << std::endl;
- }
-
- outlist = (char *) malloc(ret);
- ret = ceph_listxattr(cmount, "barfile", outlist, ret);
- if (ret < 1) {
- cerr << "ceph_listxattr error (b): should have returned > 0" << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_listxattr: success" << std::endl;
- }
- void *aybabtu;
- aybabtu = malloc(8);
- ret = ceph_getxattr(cmount, "barfile", "user.testxattr", aybabtu, 7);
- if (ret < 1) {
- cerr << "ceph_getxattr error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_getxattr: success" << std::endl;
- }
- char aybabtu_reference[]="AYBABTU";
- if (strncmp((char *) aybabtu, aybabtu_reference,7)) {
- cerr << "ceph_getxattr error: no match (" << aybabtu << ") should be (" << aybabtu_reference << cpp_strerror(ret) << std::endl;
- }
- ret = ceph_close(cmount,my_fd);
- if (ret < 0) {
- cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_close: success" << std::endl;
- }
-
-
- cout << "Attempting lstat on '/.'" << std::endl;
- ret = ceph_lstat(cmount, "/.", &stbuf);
- if (ret) {
- cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_lstat: success" << std::endl;
- }
- cout << "Attempting lstat on '.'" << std::endl;
- ret = ceph_lstat(cmount, ".", &stbuf);
- if (ret) {
- cerr << "ceph_lstat error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_lstat: success" << std::endl;
- }
- cout << "Setting up readdir test" << std::endl;
- ret = ceph_mkdir(cmount, "readdir_test", 0777);
- if (ret) {
- cerr << "ceph_mkdir error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_mkdir: success" << std::endl;
- }
- my_fd = ret = ceph_open(cmount, "readdir_test/opened_file_1", O_CREAT, 0666);
- if (ret < 0) {
- cerr << "ceph_open O_CREAT error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_open: success" << std::endl;
- }
- ret = ceph_close(cmount, my_fd);
- if (ret < 0) {
- cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_close: success" << std::endl;
- }
-
- // test empty name components
- my_fd = ret = ceph_open(cmount, "readdir_test//opened_file_1", O_RDONLY, 0666);
- if (ret < 0) {
- cerr << "ceph_open O_RDONLY error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_open: success" << std::endl;
- }
- ret = ceph_close(cmount, my_fd);
- if (ret < 0) {
- cerr << "ceph_close error: " << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_close: success" << std::endl;
- }
-
- struct ceph_dir_result *readdir_test_dir;
- ret = ceph_opendir(cmount, "readdir_test", &readdir_test_dir);
- if (ret != 0) {
- cerr << "ceph_opendir error: unexpected result from trying to open readdir_test: "
- << cpp_strerror(ret) << std::endl;
- return 1;
- } else {
- cout << "ceph_opendir: success" << std::endl;
- }
- cout << "Attempting readdir on opened directory..." << std::endl;
- struct dirent * result;
- //result = (struct dirent *) malloc(sizeof(struct dirent));
- result = ceph_readdir(cmount, readdir_test_dir);
- if (result == (dirent *) NULL) {
- cout << "ceph_readdir: failed to read any entries" << std::endl;
- }
- loff_t telldir_result;
- while ( result != (dirent *) NULL) {
- cout << "ceph_readdir: dirent->d_name: (" << result->d_name << ")" << std::endl;
- cout << "ceph_telldir: starting" << std::endl;
- telldir_result = ceph_telldir(cmount, readdir_test_dir);
- if (telldir_result > -1) {
- cout << "ceph_telldir: offset: from return code:" << telldir_result << std::endl;
- } else {
- cout << "ceph_telldir: failed" << std::endl;
- }
- cout << "ceph_readdir: lookup success: trying for another..." << std::endl;
- result = ceph_readdir(cmount, readdir_test_dir);
- }
- cout << "ceph_readdir: finished" << std::endl;
-
- // tell us that we're at the end of the directory:
- cout << "ceph_telldir: starting" << std::endl;
- telldir_result = ceph_telldir(cmount, readdir_test_dir);
- if (telldir_result > -1) {
- cout << "ceph_telldir: offset: from return code:" << telldir_result << std::endl;
- } else {
- cout << "ceph_telldir: failed" << std::endl;
- }
-
- ret = ceph_closedir(cmount,readdir_test_dir);
- if (ret == 0) {
- cerr << "ceph_closedir success" << std::endl;
- } else {
- cerr << "ceph_closedir error: " << cpp_strerror(ret) << std::endl;
- }
-
- ceph_shutdown(cmount);
-
- return 0;
-}
#include <sys/fcntl.h>
#include <unistd.h>
#include <sys/types.h>
+#include <dirent.h>
+#include <sys/xattr.h>
TEST(LibCephFS, Open_empty_component) {
ASSERT_EQ(0, ceph_conf_read_file(cmount, NULL));
ASSERT_NE(0, ceph_mount(cmount, "/non-exist"));
}
+
+TEST(LibCephFS, Mount) {
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+ ceph_shutdown(cmount);
+
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+ ceph_shutdown(cmount);
+}
+
+TEST(LibCephFS, Dir_ls) {
+
+ pid_t mypid = getpid();
+
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, "/"), 0);
+
+ struct ceph_dir_result *ls_dir = NULL;
+ char foostr[256];
+ sprintf(foostr, "dir_ls%d", mypid);
+ ASSERT_EQ(ceph_opendir(cmount, foostr, &ls_dir), -ENOENT);
+
+ ASSERT_EQ(ceph_mkdir(cmount, foostr, 0777), 0);
+ struct stat stbuf;
+ ASSERT_EQ(ceph_lstat(cmount, foostr, &stbuf), 0);
+ ASSERT_NE(S_ISDIR(stbuf.st_mode), 0);
+
+ char barstr[256];
+ sprintf(barstr, "dir_ls2%d", mypid);
+ ASSERT_EQ(ceph_lstat(cmount, barstr, &stbuf), -ENOENT);
+
+ // insert files into directory and test open
+ char bazstr[256];
+ int i = 0, r = rand() % 4096;
+ for(; i < r; ++i) {
+
+ sprintf(bazstr, "dir_ls%d/dirf%d", mypid, i);
+ int fd = ceph_open(cmount, bazstr, O_CREAT|O_RDONLY, 0666);
+ ASSERT_GT(fd, 0);
+ ASSERT_EQ(ceph_close(cmount, fd), 0);
+
+ // set file sizes for readdirplus
+ ceph_truncate(cmount, bazstr, i);
+ }
+
+ ASSERT_EQ(ceph_opendir(cmount, foostr, &ls_dir), 0);
+
+ // not guaranteed to get . and .. first, but its a safe assumption in this case
+ struct dirent *result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, ".");
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, "..");
+
+ std::vector<std::pair<char *, int> > entries;
+ // check readdir and capture stream order for future tests
+ for(i = 0; i < r; ++i) {
+
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+
+ int size;
+ sscanf(result->d_name, "dirf%d", &size);
+ entries.push_back(std::pair<char*,int>(strdup(result->d_name), size));
+ }
+
+ ASSERT_TRUE(ceph_readdir(cmount, ls_dir) == NULL);
+
+ // test rewinddir
+ ceph_rewinddir(cmount, ls_dir);
+
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, ".");
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, "..");
+
+ // check telldir
+ for(i = 0; i < r-1; ++i) {
+ int r = ceph_telldir(cmount, ls_dir);
+ ASSERT_GT(r, -1);
+ ceph_seekdir(cmount, ls_dir, r);
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, entries[i].first);
+ }
+
+ int t = ceph_telldir(cmount, ls_dir);
+ ASSERT_GT(t, -1);
+
+ ceph_rewinddir(cmount, ls_dir);
+
+ // test seekdir - move to end
+ ceph_seekdir(cmount, ls_dir, t);
+
+ // check that we're at the end
+ ASSERT_TRUE(ceph_readdir(cmount, ls_dir) != NULL);
+ ASSERT_TRUE(ceph_readdir(cmount, ls_dir) == NULL);
+
+ ceph_rewinddir(cmount, ls_dir);
+
+ // test getdents
+ struct dirent *getdents_entries;
+ getdents_entries = (struct dirent *)malloc(r * sizeof(*getdents_entries));
+
+ int count = 0;
+ while (count < r) {
+ int len = ceph_getdents(cmount, ls_dir, (char *)getdents_entries, r * sizeof(*getdents_entries));
+ ASSERT_GT(len, 0);
+ ASSERT_TRUE((len % sizeof(*getdents_entries)) == 0);
+ int n = len / sizeof(*getdents_entries);
+ if (count == 0) {
+ ASSERT_STREQ(getdents_entries[0].d_name, ".");
+ ASSERT_STREQ(getdents_entries[1].d_name, "..");
+ }
+ int j;
+ i = count;
+ for(j = 2; j < n; ++i, ++j) {
+ ASSERT_STREQ(getdents_entries[j].d_name, entries[i].first);
+ }
+ count += n;
+ }
+
+ free(getdents_entries);
+
+ // test readdir_r
+ ceph_rewinddir(cmount, ls_dir);
+
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, ".");
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, "..");
+
+ for(i = 0; i < r; ++i) {
+ struct dirent rdent;
+ ASSERT_EQ(ceph_readdir_r(cmount, ls_dir, &rdent), 1);
+ ASSERT_STREQ(rdent.d_name, entries[i].first);
+ }
+
+ // test readdirplus
+ ceph_rewinddir(cmount, ls_dir);
+
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, ".");
+ result = ceph_readdir(cmount, ls_dir);
+ ASSERT_TRUE(result != NULL);
+ ASSERT_STREQ(result->d_name, "..");
+
+ for(i = 0; i < r; ++i) {
+ struct dirent rdent;
+ struct stat st;
+ int stmask;
+ ASSERT_EQ(ceph_readdirplus_r(cmount, ls_dir, &rdent, &st, &stmask), 1);
+ ASSERT_STREQ(rdent.d_name, entries[i].first);
+ ASSERT_EQ(st.st_size, entries[i].second);
+ ASSERT_EQ(st.st_ino, rdent.d_ino);
+ //ASSERT_EQ(st.st_mode, (mode_t)0666);
+ }
+
+ ASSERT_EQ(ceph_closedir(cmount, ls_dir), 0);
+
+ ceph_shutdown(cmount);
+}
+
+TEST(LibCephFS, Many_nested_dirs) {
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+
+ const char *many_path = "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a";
+ ASSERT_EQ(ceph_mkdirs(cmount, many_path, 0755), 0);
+
+ int i = 0;
+
+ for(; i < 39; ++i) {
+ ASSERT_EQ(ceph_chdir(cmount, "a"), 0);
+
+ struct ceph_dir_result *dirp;
+ ASSERT_EQ(ceph_opendir(cmount, "a", &dirp), 0);
+ struct dirent *dent = ceph_readdir(cmount, dirp);
+ ASSERT_TRUE(dent != NULL);
+ ASSERT_STREQ(dent->d_name, ".");
+ dent = ceph_readdir(cmount, dirp);
+ ASSERT_TRUE(dent != NULL);
+ ASSERT_STREQ(dent->d_name, "..");
+ dent = ceph_readdir(cmount, dirp);
+ ASSERT_TRUE(dent != NULL);
+ ASSERT_STREQ(dent->d_name, "a");
+ ASSERT_EQ(ceph_closedir(cmount, dirp), 0);
+ }
+
+ ASSERT_STREQ(ceph_getcwd(cmount), "/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a");
+
+ ASSERT_EQ(ceph_chdir(cmount, "a/a/a"), 0);
+
+ for(i = 0; i < 39; ++i) {
+ ASSERT_EQ(ceph_chdir(cmount, ".."), 0);
+ ASSERT_EQ(ceph_rmdir(cmount, "a"), 0);
+ }
+
+ ASSERT_EQ(ceph_chdir(cmount, "/"), 0);
+
+ ASSERT_EQ(ceph_rmdir(cmount, "a/a/a"), 0);
+
+ ceph_shutdown(cmount);
+}
+
+TEST(LibCephFS, Xattrs) {
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+
+ char test_xattr_file[256];
+ sprintf(test_xattr_file, "test_xattr_%d", getpid());
+ int fd = ceph_open(cmount, test_xattr_file, O_CREAT, 0666);
+ ASSERT_GT(fd, 0);
+
+ char i = 'a';
+ char xattrk[128];
+ char xattrv[128];
+ for(; i < 'a'+26; ++i) {
+ sprintf(xattrk, "user.test_xattr_%c", i);
+ int len = sprintf(xattrv, "testxattr%c", i);
+ ASSERT_EQ(ceph_setxattr(cmount, test_xattr_file, xattrk, (void *) xattrv, len, XATTR_CREATE), 0);
+ }
+
+ char xattrlist[128*26];
+ int len = ceph_listxattr(cmount, test_xattr_file, xattrlist, sizeof(xattrlist));
+ char *p = xattrlist;
+ char *n;
+ i = 'a';
+ while(len > 0) {
+ sprintf(xattrk, "user.test_xattr_%c", i);
+ ASSERT_STREQ(p, xattrk);
+
+ char gxattrv[128];
+ int alen = ceph_getxattr(cmount, test_xattr_file, p, (void *) gxattrv, 128);
+ sprintf(xattrv, "testxattr%c", i);
+ ASSERT_TRUE(!strncmp(xattrv, gxattrv, alen));
+
+ n = index(p, '\0');
+ n++;
+ len -= (n - p);
+ p = n;
+ ++i;
+ }
+
+ i = 'a';
+ for(i = 'a'; i < 'a'+26; ++i) {
+ sprintf(xattrk, "user.test_xattr_%c", i);
+ ASSERT_EQ(ceph_removexattr(cmount, test_xattr_file, xattrk), 0);
+ }
+
+ ceph_close(cmount, fd);
+ ceph_shutdown(cmount);
+}
+
+TEST(LibCephFS, Lstat_slashdot) {
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+
+ struct stat stbuf;
+ ASSERT_EQ(ceph_lstat(cmount, "/.", &stbuf), 0);
+ ASSERT_EQ(ceph_lstat(cmount, ".", &stbuf), 0);
+
+ ceph_shutdown(cmount);
+}