From cbc084f9e06ca589768f5a84699b476721db9fd6 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sun, 1 Jan 2017 14:11:04 -0500 Subject: [PATCH] LU-8066 obdclass: move lustre sysctl to sysfs Backport from upstream the changes to port lustre systctl to sysfs. Needed to re-export the function lprocfs_read_frac_helper for later work. The following patches were backported: Fix class_procfs_init error return value. Dan Carpenter noticed that procfs conversion patches introduced a bug where should kobject_create_and_add, an error is not returned from class_procfs_init. Linux-commit: 3c4872f94359ed38a1392c0a9238c48a9aee6f8f Move sysctl timeout to sysfs. This is the first step of moving lustre sysctls from /proc/sys/lustre to /sys/fs/lustre Linux-commit: e2424a1265f2772b66f068c205256e2aef5f74a0 Move max_dirty_mb from sysctl to sysfs. max_dirty_mb is now a parameter in /sys/fs/lustre. Linux-commit: df476a4d5de09d9324b108fc9c5ff2c00a0850d0 Move debug controls to sysfs. debug_peer_on_timeout, dump_on_timeout and dump_on_eviction controls from /proc/sys/lustre to /sys/fs/lustre Linux-commit: 9e7fa14935901bcd09576b2866d5dd15f69caf83 Move AT controls from sysctl to sysfs. Adaptive Timeouts controls are being moved from /proc/sys/lustre to /sys/fs/lustre Linux-commit: bcef118e7ed67e28edcaab9be9ca11412176c540 Signed-off-by: Oleg Drokin Change-Id: Id1b00bebf9ecca5284e9c71f4c0f91e56cbf391b Reported-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/23428 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Dmitry Eremin --- lustre/include/obd_class.h | 4 +- lustre/obdclass/linux/linux-module.c | 8 +- lustre/obdclass/linux/linux-sysctl.c | 252 +++++++++++++++-------------------- lustre/obdclass/lprocfs_status.c | 1 + 4 files changed, 118 insertions(+), 147 deletions(-) diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index d63bdd7..46fe25e 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1671,8 +1671,8 @@ int lustre_unregister_fs(void); int lustre_check_exclusion(struct super_block *sb, char *svname); /* sysctl.c */ -extern void obd_sysctl_init (void); -extern void obd_sysctl_clean (void); +extern int obd_sysctl_init(void); +extern void obd_sysctl_clean(void); /* uuid.c */ typedef __u8 class_uuid_t[16]; diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c index a2d69d7..0825d8f 100644 --- a/lustre/obdclass/linux/linux-module.c +++ b/lustre/obdclass/linux/linux-module.c @@ -449,7 +449,7 @@ int class_procfs_init(void) { struct proc_dir_entry *entry; struct dentry *file; - int rc = 0; + int rc = -ENOMEM; ENTRY; lustre_kobj = kobject_create_and_add("lustre", fs_kobj); @@ -463,7 +463,11 @@ int class_procfs_init(void) goto out; } - obd_sysctl_init(); + rc = obd_sysctl_init(); + if (rc) { + kobject_put(lustre_kobj); + goto out; + } debugfs_lustre_root = debugfs_create_dir("lustre", NULL); if (IS_ERR_OR_NULL(debugfs_lustre_root)) { diff --git a/lustre/obdclass/linux/linux-sysctl.c b/lustre/obdclass/linux/linux-sysctl.c index af1d19c..c066b0c 100644 --- a/lustre/obdclass/linux/linux-sysctl.c +++ b/lustre/obdclass/linux/linux-sysctl.c @@ -54,18 +54,53 @@ static struct ctl_table_header *obd_table_header; #endif -static int -proc_set_timeout(struct ctl_table *table, int write, void __user *buffer, - size_t *lenp, loff_t *ppos) +struct static_lustre_uintvalue_attr { + struct { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, struct attribute *attr, + char *buf); + ssize_t (*store)(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len); + } u; + int *value; +}; + +static ssize_t static_uintvalue_show(struct kobject *kobj, + struct attribute *attr, + char *buf) +{ + struct static_lustre_uintvalue_attr *lattr = (void *)attr; + + return sprintf(buf, "%d\n", *lattr->value); +} + +static ssize_t static_uintvalue_store(struct kobject *kobj, + struct attribute *attr, + const char *buffer, size_t count) { - int rc; + struct static_lustre_uintvalue_attr *lattr = (void *)attr; + unsigned int val; + int rc; + + rc = kstrtouint(buffer, 10, &val); + if (rc) + return rc; + + *lattr->value = val; - rc = proc_dointvec(table, write, buffer, lenp, ppos); - if (ldlm_timeout >= obd_timeout) - ldlm_timeout = max(obd_timeout / 3, 1U); - return rc; + return count; } +#define LUSTRE_STATIC_UINT_ATTR(name, value) \ +static struct static_lustre_uintvalue_attr lustre_sattr_##name = \ + {__ATTR(name, 0644, \ + static_uintvalue_show, \ + static_uintvalue_store),\ + value } + +LUSTRE_STATIC_UINT_ATTR(timeout, &obd_timeout); + +#ifdef CONFIG_SYSCTL static int proc_memory_alloc(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) @@ -115,95 +150,60 @@ proc_mem_max(struct ctl_table *table, int write, void __user *buffer, *ppos += *lenp; return 0; } +#endif /* CONFIG_SYSCTL */ -static int -proc_max_dirty_pages_in_mb(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) +static ssize_t max_dirty_mb_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + return sprintf(buf, "%lu\n", + obd_max_dirty_pages / (1 << (20 - PAGE_SHIFT))); +} + +static ssize_t max_dirty_mb_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) { - __s64 val; - int rc = 0; + unsigned long val; + int rc; + + rc = kstrtoul(buffer, 10, &val); + if (rc) + return rc; + + val *= 1 << (20 - PAGE_SHIFT); /* convert to pages */ - if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) { - *lenp = 0; - return 0; + if (val > ((totalram_pages / 10) * 9)) { + /* Somebody wants to assign too much memory to dirty pages */ + return -EINVAL; } - if (write) { - rc = lprocfs_str_with_units_to_s64(buffer, *lenp, &val, 'M'); - if (rc) - return rc; - - if (val < 0) - return -ERANGE; - - val >>= PAGE_SHIFT; - - /* Don't allow them to let dirty pages exceed 90% of system - * memory and set a hard minimum of 4MB. */ - if (val > ((totalram_pages / 10) * 9)) { - CERROR("Refusing to set max dirty pages to %lld, " - "which is more than 90%% of available RAM; " - "setting to %lu\n", val, - ((totalram_pages / 10) * 9)); - obd_max_dirty_pages = ((totalram_pages / 10) * 9); - } else if (val < 4 << (20 - PAGE_SHIFT)) { - obd_max_dirty_pages = 4 << (20 - PAGE_SHIFT); - } else { - obd_max_dirty_pages = val; - } - } else { - char buf[21]; - int len; - - len = lprocfs_read_frac_helper(buf, sizeof(buf), - *(unsigned long *)table->data, - 1 << (20 - PAGE_SHIFT)); - if (len > *lenp) - len = *lenp; - buf[len] = '\0'; - if (copy_to_user(buffer, buf, len)) - return -EFAULT; - *lenp = len; + + if (val < 4 << (20 - PAGE_SHIFT)) { + /* Less than 4 Mb for dirty cache is also bad */ + return -EINVAL; } - *ppos += *lenp; - return rc; + + obd_max_dirty_pages = val; + + return count; } +LUSTRE_RW_ATTR(max_dirty_mb); + +LUSTRE_STATIC_UINT_ATTR(debug_peer_on_timeout, &obd_debug_peer_on_timeout); +LUSTRE_STATIC_UINT_ATTR(dump_on_timeout, &obd_dump_on_timeout); +LUSTRE_STATIC_UINT_ATTR(dump_on_eviction, &obd_dump_on_eviction); +LUSTRE_STATIC_UINT_ATTR(at_min, &at_min); +LUSTRE_STATIC_UINT_ATTR(at_max, &at_max); +LUSTRE_STATIC_UINT_ATTR(at_extra, &at_extra); +LUSTRE_STATIC_UINT_ATTR(at_early_margin, &at_early_margin); +LUSTRE_STATIC_UINT_ATTR(at_history, &at_history); + +#ifdef HAVE_SERVER_SUPPORT +LUSTRE_STATIC_UINT_ATTR(ldlm_timeout, &ldlm_timeout); +#endif #ifdef CONFIG_SYSCTL static struct ctl_table obd_table[] = { { INIT_CTL_NAME - .procname = "timeout", - .data = &obd_timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_set_timeout - }, - { - INIT_CTL_NAME - .procname = "debug_peer_on_timeout", - .data = &obd_debug_peer_on_timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME - .procname = "dump_on_timeout", - .data = &obd_dump_on_timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME - .procname = "dump_on_eviction", - .data = &obd_dump_on_eviction, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME .procname = "memused", .data = NULL, .maxlen = 0, @@ -220,68 +220,12 @@ static struct ctl_table obd_table[] = { }, { INIT_CTL_NAME - .procname = "ldlm_timeout", - .data = &ldlm_timeout, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_set_timeout - }, - { - INIT_CTL_NAME - .procname = "max_dirty_mb", - .data = &obd_max_dirty_pages, - .maxlen = sizeof(unsigned long), - .mode = 0644, - .proc_handler = &proc_max_dirty_pages_in_mb - }, - { - INIT_CTL_NAME .procname = "bulk_timeout", .data = &bulk_timeout, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec }, - { - INIT_CTL_NAME - .procname = "at_min", - .data = &at_min, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME - .procname = "at_max", - .data = &at_max, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME - .procname = "at_extra", - .data = &at_extra, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME - .procname = "at_early_margin", - .data = &at_early_margin, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, - { - INIT_CTL_NAME - .procname = "at_history", - .data = &at_history, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec - }, { 0 } }; @@ -298,12 +242,34 @@ static struct ctl_table parent_table[] = { }; #endif -void obd_sysctl_init (void) +static struct attribute *lustre_attrs[] = { + &lustre_sattr_timeout.u.attr, + &lustre_attr_max_dirty_mb.attr, + &lustre_sattr_debug_peer_on_timeout.u.attr, + &lustre_sattr_dump_on_timeout.u.attr, + &lustre_sattr_dump_on_eviction.u.attr, + &lustre_sattr_at_min.u.attr, + &lustre_sattr_at_max.u.attr, + &lustre_sattr_at_extra.u.attr, + &lustre_sattr_at_early_margin.u.attr, + &lustre_sattr_at_history.u.attr, +#ifdef HAVE_SERVER_SUPPORT + &lustre_sattr_ldlm_timeout.u.attr, +#endif + NULL, +}; + +static struct attribute_group lustre_attr_group = { + .attrs = lustre_attrs, +}; + +int obd_sysctl_init(void) { #ifdef CONFIG_SYSCTL if ( !obd_table_header ) obd_table_header = register_sysctl_table(parent_table); #endif + return sysfs_create_group(lustre_kobj, &lustre_attr_group); } void obd_sysctl_clean (void) diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 7bb366b..80621f6 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -1800,6 +1800,7 @@ int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val, buffer[prtn++] ='\n'; return prtn; } +EXPORT_SYMBOL(lprocfs_read_frac_helper); int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult) { -- 1.8.3.1