}
}
-/**
- * create /proc entries for coordinator
- * \param mdt [IN]
- * \retval 0 success
- * \retval -ve failure
- */
-int hsm_cdt_procfs_init(struct mdt_device *mdt)
-{
- struct coordinator *cdt = &mdt->mdt_coordinator;
- int rc = 0;
- ENTRY;
-
- /* init /proc entries, failure is not critical */
- cdt->cdt_proc_dir = lprocfs_register("hsm",
- mdt2obd_dev(mdt)->obd_proc_entry,
- lprocfs_mdt_hsm_vars, mdt);
- if (IS_ERR(cdt->cdt_proc_dir)) {
- rc = PTR_ERR(cdt->cdt_proc_dir);
- CERROR("%s: Cannot create 'hsm' directory in mdt proc dir,"
- " rc=%d\n", mdt_obd_name(mdt), rc);
- cdt->cdt_proc_dir = NULL;
- RETURN(rc);
- }
-
- RETURN(0);
-}
-
-/**
- * remove /proc entries for coordinator
- * \param mdt [IN]
- */
-void hsm_cdt_procfs_fini(struct mdt_device *mdt)
-{
- struct coordinator *cdt = &mdt->mdt_coordinator;
-
- if (cdt->cdt_proc_dir != NULL)
- lprocfs_remove(&cdt->cdt_proc_dir);
-}
-
-/**
- * get vector of hsm cdt /proc vars
- * \param none
- * \retval var vector
- */
-struct lprocfs_vars *hsm_cdt_get_proc_vars(void)
-{
- return lprocfs_mdt_hsm_vars;
-}
-
/* Release the ressource used by the coordinator. Called when the
* coordinator is stopping. */
static void mdt_hsm_cdt_cleanup(struct mdt_device *mdt)
hsm_init_ucred(mdt_ucred(cdt_mti));
- /* default values for /proc tunnables
+ /* default values for sysfs tunnables
* can be override by MGS conf */
cdt->cdt_default_archive_id = 1;
cdt->cdt_grace_delay = 60;
cdt->cdt_group_request_mask = (1UL << HSMA_RESTORE);
cdt->cdt_other_request_mask = (1UL << HSMA_RESTORE);
- /* to avoid deadlock when start is made through /proc
- * /proc entries are created by the coordinator thread */
-
+ /* to avoid deadlock when start is made through sysfs
+ * sysfs entries are created by the coordinator thread
+ */
/* set up list of started restore requests */
cdt_mti = lu_context_key_get(&cdt->cdt_env.le_ctx, &mdt_thread_key);
rc = mdt_hsm_pending_restore(cdt_mti);
}
/*
- * /proc interface used to get/set HSM behaviour (cdt->cdt_policy)
+ * sysfs interface used to get/set HSM behaviour (cdt->cdt_policy)
*/
static const struct {
__u64 bit;
OBD_FREE(buf, count + 1);
RETURN(rc);
}
-LPROC_SEQ_FOPS(mdt_hsm_policy);
-
-#define GENERATE_PROC_METHOD(VAR) \
-static int mdt_hsm_##VAR##_seq_show(struct seq_file *m, void *data) \
-{ \
- struct mdt_device *mdt = m->private; \
- struct coordinator *cdt = &mdt->mdt_coordinator; \
- ENTRY; \
- \
- seq_printf(m, "%llu\n", (__u64)cdt->VAR); \
- RETURN(0); \
-} \
-static ssize_t \
-mdt_hsm_##VAR##_seq_write(struct file *file, const char __user *buffer, \
- size_t count, loff_t *off) \
- \
-{ \
- struct seq_file *m = file->private_data; \
- struct mdt_device *mdt = m->private; \
- struct coordinator *cdt = &mdt->mdt_coordinator; \
- unsigned int val; \
- int rc; \
- \
- ENTRY; \
- rc = kstrtouint_from_user(buffer, count, 0, &val); \
- if (rc) \
- RETURN(rc); \
- \
- if (val != 0) { \
- cdt->VAR = val; \
- RETURN(count); \
- } \
- RETURN(-EINVAL); \
-} \
-
-GENERATE_PROC_METHOD(cdt_loop_period)
-GENERATE_PROC_METHOD(cdt_grace_delay)
-GENERATE_PROC_METHOD(cdt_active_req_timeout)
-GENERATE_PROC_METHOD(cdt_max_requests)
-GENERATE_PROC_METHOD(cdt_default_archive_id)
+LDEBUGFS_SEQ_FOPS(mdt_hsm_policy);
+
+ssize_t loop_period_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+
+ return scnprintf(buf, PAGE_SIZE, "%lu\n", cdt->cdt_loop_period);
+}
+
+ssize_t loop_period_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+ unsigned int val;
+ int rc;
+
+ rc = kstrtouint(buffer, 0, &val);
+ if (rc)
+ return rc;
+
+ if (val != 0)
+ cdt->cdt_loop_period = val;
+
+ return val ? count : -EINVAL;
+}
+LUSTRE_RW_ATTR(loop_period);
+
+ssize_t grace_delay_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+
+ return scnprintf(buf, PAGE_SIZE, "%lu\n", cdt->cdt_grace_delay);
+}
+
+ssize_t grace_delay_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+ unsigned int val;
+ int rc;
+
+ rc = kstrtouint(buffer, 0, &val);
+ if (rc)
+ return rc;
+
+ if (val != 0)
+ cdt->cdt_grace_delay = val;
+
+ return val ? count : -EINVAL;
+}
+LUSTRE_RW_ATTR(grace_delay);
+
+ssize_t active_request_timeout_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+
+ return scnprintf(buf, PAGE_SIZE, "%lu\n", cdt->cdt_active_req_timeout);
+}
+
+ssize_t active_request_timeout_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+ unsigned int val;
+ int rc;
+
+ rc = kstrtouint(buffer, 0, &val);
+ if (rc)
+ return rc;
+
+ if (val != 0)
+ cdt->cdt_active_req_timeout = val;
+
+ return val ? count : -EINVAL;
+}
+LUSTRE_RW_ATTR(active_request_timeout);
+
+ssize_t max_requests_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+
+ return scnprintf(buf, PAGE_SIZE, "%llu\n", cdt->cdt_max_requests);
+}
+
+ssize_t max_requests_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+ unsigned long long val;
+ int rc;
+
+ rc = kstrtoull(buffer, 0, &val);
+ if (rc)
+ return rc;
+
+ if (val != 0)
+ cdt->cdt_max_requests = val;
+
+ return val ? count : -EINVAL;
+}
+LUSTRE_RW_ATTR(max_requests);
+
+ssize_t default_archive_id_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", cdt->cdt_default_archive_id);
+}
+
+ssize_t default_archive_id_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+ unsigned int val;
+ int rc;
+
+ rc = kstrtouint(buffer, 0, &val);
+ if (rc)
+ return rc;
+
+ if (val != 0)
+ cdt->cdt_default_archive_id = val;
+
+ return val ? count : -EINVAL;
+}
+LUSTRE_RW_ATTR(default_archive_id);
/*
* procfs write method for MDT/hsm_control
#define CDT_HELP_CMD "help"
#define CDT_MAX_CMD_LEN 10
-ssize_t
-mdt_hsm_cdt_control_seq_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *off)
+ssize_t hsm_control_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- struct coordinator *cdt = &(mdt->mdt_coordinator);
- int rc, usage = 0;
- char kernbuf[CDT_MAX_CMD_LEN];
- ENTRY;
-
- if (count == 0 || count >= sizeof(kernbuf))
- RETURN(-EINVAL);
-
- if (copy_from_user(kernbuf, buffer, count))
- RETURN(-EFAULT);
- kernbuf[count] = 0;
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ struct coordinator *cdt = &(mdt->mdt_coordinator);
+ int usage = 0;
+ int rc = 0;
- if (kernbuf[count - 1] == '\n')
- kernbuf[count - 1] = 0;
+ if (count == 0 || count >= CDT_MAX_CMD_LEN)
+ return -EINVAL;
- rc = 0;
- if (strcmp(kernbuf, CDT_ENABLE_CMD) == 0) {
+ if (strncmp(buffer, CDT_ENABLE_CMD, strlen(CDT_ENABLE_CMD)) == 0) {
if (cdt->cdt_state == CDT_DISABLE) {
rc = set_cdt_state(cdt, CDT_RUNNING);
mdt_hsm_cdt_event(cdt);
} else {
rc = mdt_hsm_cdt_start(mdt);
}
- } else if (strcmp(kernbuf, CDT_STOP_CMD) == 0) {
+ } else if (strncmp(buffer, CDT_STOP_CMD, strlen(CDT_STOP_CMD)) == 0) {
if ((cdt->cdt_state == CDT_STOPPING) ||
(cdt->cdt_state == CDT_STOPPED)) {
CERROR("%s: Coordinator already stopped\n",
} else {
rc = mdt_hsm_cdt_stop(mdt);
}
- } else if (strcmp(kernbuf, CDT_DISABLE_CMD) == 0) {
+ } else if (strncmp(buffer, CDT_DISABLE_CMD,
+ strlen(CDT_DISABLE_CMD)) == 0) {
if ((cdt->cdt_state == CDT_STOPPING) ||
(cdt->cdt_state == CDT_STOPPED)) {
CERROR("%s: Coordinator is stopped\n",
} else {
rc = set_cdt_state(cdt, CDT_DISABLE);
}
- } else if (strcmp(kernbuf, CDT_PURGE_CMD) == 0) {
+ } else if (strncmp(buffer, CDT_PURGE_CMD,
+ strlen(CDT_PURGE_CMD)) == 0) {
rc = hsm_cancel_all_actions(mdt);
- } else if (strcmp(kernbuf, CDT_HELP_CMD) == 0) {
+ } else if (strncmp(buffer, CDT_HELP_CMD,
+ strlen(CDT_HELP_CMD)) == 0) {
usage = 1;
} else {
usage = 1;
RETURN(count);
}
-int mdt_hsm_cdt_control_seq_show(struct seq_file *m, void *data)
+ssize_t hsm_control_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct obd_device *obd = m->private;
- struct coordinator *cdt;
- ENTRY;
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct coordinator *cdt;
cdt = &(mdt_dev(obd->obd_lu_dev)->mdt_coordinator);
- seq_printf(m, "%s\n", cdt_mdt_state2str(cdt->cdt_state));
-
- RETURN(0);
+ return scnprintf(buf, PAGE_SIZE, "%s\n",
+ cdt_mdt_state2str(cdt->cdt_state));
}
static int
&cdt->cdt_other_request_mask);
}
-static int mdt_hsm_cdt_raolu_seq_show(struct seq_file *m, void *data)
+static ssize_t remove_archive_on_last_unlink_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
{
- struct mdt_device *mdt = m->private;
- struct coordinator *cdt = &mdt->mdt_coordinator;
- ENTRY;
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
- seq_printf(m, "%d\n", (int)cdt->cdt_remove_archive_on_last_unlink);
- RETURN(0);
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
+ cdt->cdt_remove_archive_on_last_unlink);
}
-static ssize_t
-mdt_hsm_cdt_raolu_seq_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *off)
-
+static ssize_t remove_archive_on_last_unlink_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer,
+ size_t count)
{
- struct seq_file *m = file->private_data;
- struct mdt_device *mdt = m->private;
- struct coordinator *cdt = &mdt->mdt_coordinator;
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
bool val;
int rc;
- ENTRY;
- rc = kstrtobool_from_user(buffer, count, &val);
+ rc = kstrtobool(buffer, &val);
if (rc < 0)
- RETURN(rc);
+ return rc;
cdt->cdt_remove_archive_on_last_unlink = val;
- RETURN(count);
+ return count;
}
+LUSTRE_RW_ATTR(remove_archive_on_last_unlink);
+
+LDEBUGFS_SEQ_FOPS(mdt_hsm_user_request_mask);
+LDEBUGFS_SEQ_FOPS(mdt_hsm_group_request_mask);
+LDEBUGFS_SEQ_FOPS(mdt_hsm_other_request_mask);
-LPROC_SEQ_FOPS(mdt_hsm_cdt_loop_period);
-LPROC_SEQ_FOPS(mdt_hsm_cdt_grace_delay);
-LPROC_SEQ_FOPS(mdt_hsm_cdt_active_req_timeout);
-LPROC_SEQ_FOPS(mdt_hsm_cdt_max_requests);
-LPROC_SEQ_FOPS(mdt_hsm_cdt_default_archive_id);
-LPROC_SEQ_FOPS(mdt_hsm_user_request_mask);
-LPROC_SEQ_FOPS(mdt_hsm_group_request_mask);
-LPROC_SEQ_FOPS(mdt_hsm_other_request_mask);
-LPROC_SEQ_FOPS(mdt_hsm_cdt_raolu);
-
-/* Read-only proc files for request counters */
-static int mdt_hsm_cdt_archive_count_seq_show(struct seq_file *m, void *data)
+/* Read-only sysfs files for request counters */
+static ssize_t archive_count_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct mdt_device *mdt = m->private;
- struct coordinator *cdt = &mdt->mdt_coordinator;
- ENTRY;
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
- seq_printf(m, "%d\n", atomic_read(&cdt->cdt_archive_count));
- RETURN(0);
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ atomic_read(&cdt->cdt_archive_count));
}
+LUSTRE_RO_ATTR(archive_count);
-static int mdt_hsm_cdt_restore_count_seq_show(struct seq_file *m, void *data)
+static ssize_t restore_count_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct mdt_device *mdt = m->private;
- struct coordinator *cdt = &mdt->mdt_coordinator;
- ENTRY;
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
- seq_printf(m, "%d\n", atomic_read(&cdt->cdt_restore_count));
- RETURN(0);
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ atomic_read(&cdt->cdt_restore_count));
}
+LUSTRE_RO_ATTR(restore_count);
-static int mdt_hsm_cdt_remove_count_seq_show(struct seq_file *m, void *data)
+static ssize_t remove_count_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct mdt_device *mdt = m->private;
- struct coordinator *cdt = &mdt->mdt_coordinator;
- ENTRY;
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
- seq_printf(m, "%d\n", atomic_read(&cdt->cdt_remove_count));
- RETURN(0);
+ return scnprintf(buf, PAGE_SIZE, "%d\n",
+ atomic_read(&cdt->cdt_remove_count));
}
-
-LPROC_SEQ_FOPS_RO(mdt_hsm_cdt_archive_count);
-LPROC_SEQ_FOPS_RO(mdt_hsm_cdt_restore_count);
-LPROC_SEQ_FOPS_RO(mdt_hsm_cdt_remove_count);
+LUSTRE_RO_ATTR(remove_count);
static struct lprocfs_vars lprocfs_mdt_hsm_vars[] = {
{ .name = "agents",
{ .name = "actions",
.fops = &mdt_hsm_actions_fops,
.proc_mode = 0444 },
- { .name = "default_archive_id",
- .fops = &mdt_hsm_cdt_default_archive_id_fops },
- { .name = "grace_delay",
- .fops = &mdt_hsm_cdt_grace_delay_fops },
- { .name = "loop_period",
- .fops = &mdt_hsm_cdt_loop_period_fops },
- { .name = "max_requests",
- .fops = &mdt_hsm_cdt_max_requests_fops },
{ .name = "policy",
.fops = &mdt_hsm_policy_fops },
- { .name = "active_request_timeout",
- .fops = &mdt_hsm_cdt_active_req_timeout_fops },
{ .name = "active_requests",
.fops = &mdt_hsm_active_requests_fops },
{ .name = "user_request_mask",
.fops = &mdt_hsm_group_request_mask_fops, },
{ .name = "other_request_mask",
.fops = &mdt_hsm_other_request_mask_fops, },
- { .name = "remove_archive_on_last_unlink",
- .fops = &mdt_hsm_cdt_raolu_fops, },
- { .name = "archive_count",
- .fops = &mdt_hsm_cdt_archive_count_fops, },
- { .name = "restore_count",
- .fops = &mdt_hsm_cdt_restore_count_fops, },
- { .name = "remove_count",
- .fops = &mdt_hsm_cdt_remove_count_fops, },
{ 0 }
};
+
+static struct attribute *hsm_attrs[] = {
+ &lustre_attr_loop_period.attr,
+ &lustre_attr_grace_delay.attr,
+ &lustre_attr_active_request_timeout.attr,
+ &lustre_attr_max_requests.attr,
+ &lustre_attr_default_archive_id.attr,
+ &lustre_attr_remove_archive_on_last_unlink.attr,
+ &lustre_attr_archive_count.attr,
+ &lustre_attr_restore_count.attr,
+ &lustre_attr_remove_count.attr,
+ NULL,
+};
+
+static void hsm_kobj_release(struct kobject *kobj)
+{
+ struct coordinator *cdt = container_of(kobj, struct coordinator,
+ cdt_hsm_kobj);
+
+ debugfs_remove_recursive(cdt->cdt_debugfs_dir);
+ cdt->cdt_debugfs_dir = NULL;
+
+ complete(&cdt->cdt_kobj_unregister);
+}
+
+static struct kobj_type hsm_ktype = {
+ .default_attrs = hsm_attrs,
+ .sysfs_ops = &lustre_sysfs_ops,
+ .release = hsm_kobj_release,
+};
+
+/**
+ * create sysfs entries for coordinator
+ * \param mdt [IN]
+ * \retval 0 success
+ * \retval -ve failure
+ */
+int hsm_cdt_tunables_init(struct mdt_device *mdt)
+{
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+ struct obd_device *obd = mdt2obd_dev(mdt);
+ int rc;
+
+ init_completion(&cdt->cdt_kobj_unregister);
+ rc = kobject_init_and_add(&cdt->cdt_hsm_kobj, &hsm_ktype,
+ &obd->obd_kset.kobj, "%s", "hsm");
+ if (rc) {
+ kobject_put(&cdt->cdt_hsm_kobj);
+ return rc;
+ }
+
+ /* init debugfs entries, failure is not critical */
+ cdt->cdt_debugfs_dir = ldebugfs_register("hsm",
+ obd->obd_debugfs_entry,
+ lprocfs_mdt_hsm_vars, mdt);
+ if (IS_ERR_OR_NULL(cdt->cdt_debugfs_dir)) {
+ rc = cdt->cdt_debugfs_dir ? PTR_ERR(cdt->cdt_debugfs_dir) :
+ -ENOMEM;
+ CERROR("%s: Cannot create 'hsm' directory in mdt proc dir, rc = %d\n",
+ mdt_obd_name(mdt), rc);
+ cdt->cdt_debugfs_dir = NULL;
+ kobject_put(&cdt->cdt_hsm_kobj);
+ return rc;
+ }
+
+ return 0;
+}
+
+/**
+ * remove sysfs entries for coordinator
+ *
+ * @mdt
+ */
+void hsm_cdt_tunables_fini(struct mdt_device *mdt)
+{
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+ kobject_put(&cdt->cdt_hsm_kobj);
+ wait_for_completion(&cdt->cdt_kobj_unregister);
+}