diff options
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-quota.c')
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-quota.c | 200 |
1 files changed, 172 insertions, 28 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-quota.c b/xlators/mgmt/glusterd/src/glusterd-quota.c index f6277a382d8..4390eaab3e6 100644 --- a/xlators/mgmt/glusterd/src/glusterd-quota.c +++ b/xlators/mgmt/glusterd/src/glusterd-quota.c @@ -94,12 +94,17 @@ glusterd_is_quota_supported (int32_t type, char **op_errstr) /* Quota xattr version implemented in 3.7.6 * quota-version is incremented when quota is enabled - * so don't allow enabling quota in heterogeneous + * Quota enable and disable performance enhancement has been done + * in version 3.7.12. + * so don't allow enabling/disabling quota in heterogeneous * cluster during upgrade */ - if (conf->op_version < GD_OP_VERSION_3_7_6 && - type == GF_QUOTA_OPTION_TYPE_ENABLE) - goto out; + if (type == GF_QUOTA_OPTION_TYPE_ENABLE || + type == GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS || + type == GF_QUOTA_OPTION_TYPE_DISABLE) { + if (conf->op_version < GD_OP_VERSION_3_7_12) + goto out; + } supported = _gf_true; @@ -229,37 +234,73 @@ out: } int32_t -glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, - int type) +_glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, + glusterd_volinfo_t *volinfo, + glusterd_brickinfo_t *brick, int type, + char *pid_dir) { pid_t pid; - int32_t ret = 0; - int status = 0; - char mountdir[] = "/tmp/mntXXXXXX"; - char logfile[PATH_MAX] = {0,}; - runner_t runner = {0}; - char *volfileserver = NULL; + int32_t ret = -1; + int status = 0; + char mountdir[PATH_MAX] = {0,}; + char logfile[PATH_MAX] = {0,}; + char brickpath[PATH_MAX] = {0,}; + char vol_id[PATH_MAX] = {0,}; + char pidfile[PATH_MAX] = {0,}; + runner_t runner = {0}; + char *volfileserver = NULL; + FILE *pidfp = NULL; + + GF_VALIDATE_OR_GOTO ("glusterd", THIS, out); + + GLUSTERD_GET_TMP_PATH (mountdir, "/"); + ret = sys_mkdir (mountdir, 0777); + if (ret && errno != EEXIST) { + gf_msg (THIS->name, GF_LOG_WARNING, errno, + GD_MSG_MOUNT_REQ_FAIL, "failed to create temporary " + "directory %s", mountdir); + ret = -1; + goto out; + } + strcat (mountdir, "mntXXXXXX"); if (mkdtemp (mountdir) == NULL) { - gf_msg_debug ("glusterd", 0, - "failed to create a temporary mount directory"); + gf_msg (THIS->name, GF_LOG_WARNING, errno, + GD_MSG_MOUNT_REQ_FAIL, "failed to create a temporary " + "mount directory: %s", mountdir); ret = -1; goto out; } + + GLUSTERD_REMOVE_SLASH_FROM_PATH (brick->path, brickpath); snprintf (logfile, sizeof (logfile), - DEFAULT_LOG_FILE_DIRECTORY"/%s-quota-crawl.log", volname); + DEFAULT_QUOTA_CRAWL_LOG_DIRECTORY"/%s.log", + brickpath); if (dict_get_str (THIS->options, "transport.socket.bind-address", &volfileserver) != 0) volfileserver = "localhost"; + snprintf (vol_id, sizeof (vol_id), "client_per_brick/%s.%s.%s.%s.vol", + volinfo->volname, "client", brick->hostname, brickpath); + runinit (&runner); - runner_add_args (&runner, SBIN_DIR"/glusterfs", - "-s", volfileserver, - "--volfile-id", volname, - "--use-readdirp=no", - "--client-pid", QUOTA_CRAWL_PID, - "-l", logfile, mountdir, NULL); + + if (type == GF_QUOTA_OPTION_TYPE_ENABLE || + type == GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS) + runner_add_args (&runner, SBIN_DIR"/glusterfs", + "-s", volfileserver, + "--volfile-id", vol_id, + "--use-readdirp=yes", + "--client-pid", QUOTA_CRAWL_PID, + "-l", logfile, mountdir, NULL); + else + runner_add_args (&runner, SBIN_DIR"/glusterfs", + "-s", volfileserver, + "--volfile-id", vol_id, + "--use-readdirp=no", + "--client-pid", QUOTA_CRAWL_PID, + "-l", logfile, mountdir, NULL); synclock_unlock (&priv->big_lock); ret = runner_run_reuse (&runner); @@ -272,7 +313,7 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, runner_end (&runner); if ((pid = fork ()) < 0) { - gf_msg ("glusterd", GF_LOG_WARNING, 0, + gf_msg (THIS->name, GF_LOG_WARNING, 0, GD_MSG_FORK_FAIL, "fork from parent failed"); ret = -1; goto out; @@ -286,7 +327,7 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, ret = chdir (mountdir); if (ret == -1) { - gf_msg ("glusterd", GF_LOG_WARNING, errno, + gf_msg (THIS->name, GF_LOG_WARNING, errno, GD_MSG_DIR_OP_FAILED, "chdir %s failed", mountdir); exit (EXIT_FAILURE); @@ -295,9 +336,7 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, if (type == GF_QUOTA_OPTION_TYPE_ENABLE || type == GF_QUOTA_OPTION_TYPE_ENABLE_OBJECTS) - runner_add_args (&runner, "/usr/bin/find", ".", - "-exec", "/usr/bin/stat", - "{}", "\\", ";", NULL); + runner_add_args (&runner, "/usr/bin/find", ".", NULL); else if (type == GF_QUOTA_OPTION_TYPE_DISABLE) { @@ -321,8 +360,19 @@ glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, char *volname, } - if (runner_start (&runner) == -1) + if (runner_start (&runner) == -1) { + gf_umount_lazy ("glusterd", mountdir, 1); _exit (EXIT_FAILURE); + } + + snprintf (pidfile, sizeof (pidfile), "%s/%s.pid", pid_dir, + brickpath); + pidfp = fopen (pidfile, "w"); + if (pidfp) { + fprintf (pidfp, "%d\n", runner.chpid); + fflush (pidfp); + fclose (pidfp); + } #ifndef GF_LINUX_HOST_OS runner_end (&runner); /* blocks in waitpid */ @@ -338,6 +388,100 @@ out: return ret; } +void +glusterd_stop_all_quota_crawl_service (glusterd_conf_t *priv, + glusterd_volinfo_t *volinfo, int type) +{ + char pid_dir[PATH_MAX] = {0, }; + char pidfile[PATH_MAX] = {0,}; + struct dirent *entry = NULL; + DIR *dir = NULL; + + GLUSTERD_GET_QUOTA_CRAWL_PIDDIR (pid_dir, volinfo, type); + + dir = sys_opendir (pid_dir); + if (dir == NULL) + return; + + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + while (entry) { + snprintf (pidfile, sizeof (pidfile), "%s/%s", + pid_dir, entry->d_name); + + glusterd_service_stop_nolock ("quota_crawl", pidfile, SIGKILL, + _gf_true); + sys_unlink (pidfile); + + GF_FOR_EACH_ENTRY_IN_DIR (entry, dir); + } + sys_closedir (dir); +} + +int32_t +glusterd_quota_initiate_fs_crawl (glusterd_conf_t *priv, + glusterd_volinfo_t *volinfo, int type) +{ + int32_t ret = -1; + glusterd_brickinfo_t *brick = NULL; + char pid_dir[PATH_MAX] = {0, }; + + GF_VALIDATE_OR_GOTO ("glusterd", THIS, out); + + ret = glusterd_generate_client_per_brick_volfile (volinfo); + if (ret) { + gf_msg (THIS->name, GF_LOG_ERROR, 0, + GD_MSG_GLUSTERD_OP_FAILED, + "failed to generate client volume file"); + goto out; + } + + ret = mkdir_p (DEFAULT_QUOTA_CRAWL_LOG_DIRECTORY, 0777, _gf_true); + if (ret) { + gf_msg (THIS->name, GF_LOG_ERROR, errno, + GD_MSG_GLUSTERD_OP_FAILED, + "failed to create dir %s: %s", + DEFAULT_QUOTA_CRAWL_LOG_DIRECTORY, strerror (errno)); + goto out; + } + + GLUSTERD_GET_QUOTA_CRAWL_PIDDIR (pid_dir, volinfo, type); + ret = mkdir_p (pid_dir, 0777, _gf_true); + if (ret) { + gf_msg (THIS->name, GF_LOG_ERROR, errno, + GD_MSG_GLUSTERD_OP_FAILED, + "failed to create dir %s: %s", + pid_dir, strerror (errno)); + goto out; + } + + /* When quota enable is performed, stop alreday running enable crawl + * process and start fresh crawl process. let disable process continue + * if running to cleanup the older xattrs + * When quota disable is performed, stop both enable/disable crawl + * process and start fresh crawl process to cleanup the xattrs + */ + glusterd_stop_all_quota_crawl_service (priv, volinfo, + GF_QUOTA_OPTION_TYPE_ENABLE); + if (type == GF_QUOTA_OPTION_TYPE_DISABLE) + glusterd_stop_all_quota_crawl_service (priv, volinfo, + GF_QUOTA_OPTION_TYPE_DISABLE); + + cds_list_for_each_entry (brick, &volinfo->bricks, brick_list) { + if (gf_uuid_compare (brick->uuid, MY_UUID)) + continue; + + ret = _glusterd_quota_initiate_fs_crawl (priv, volinfo, brick, + type, pid_dir); + + if (ret) + goto out; + } + + ret = 0; +out: + return ret; +} + int32_t glusterd_quota_get_default_soft_limit (glusterd_volinfo_t *volinfo, dict_t *rsp_dict) @@ -1539,7 +1683,7 @@ glusterd_op_quota (dict_t *dict, char **op_errstr, dict_t *rsp_dict) } if (rsp_dict && start_crawl == _gf_true) - glusterd_quota_initiate_fs_crawl (priv, volname, type); + glusterd_quota_initiate_fs_crawl (priv, volinfo, type); ret = 0; out: |
