Interesting offer
by boongrit@jomtakol.co.th
Are you Able, willing and Capable of been a Personal Assistant,
This position is an excellent opportunity for a hard-working individual who is a quick learner
and detail-oriented who is looking to provide top-level support to a busy executive.
Strong organizational skills, written and verbal communication skills, ability to anticipate needs,
work independently and prioritize workload are required.
High level of professionalism and confidentiality is crucial to this role.
The salary range for this role is $3000-$3400 per month and this doesnt disturb your present employment.
Responsibilities of the Personal Assistant:
Coordinate and schedule all appointments.
Review and analyze requests and inquiries and disseminate, as appropriate.
Processing of payments from my clients who owe{certified check mostly due to my company's policy}.
Instruction for disbursement would be sent to you, and you will make reports to me daily through email or text message.
Handle confidential and non-routine information, applying extreme confidentiality and sensitivity in the dissemination of this information.
Requirements of the Personal Assistant:
Proficient in Microsoft Office
Must be 43 years of age or older
Must be eligible to work in the USA
Have consistent access to a smartphone (iPhone 4s/Android 4.0 or newer)
Ability to anticipate future needs and prepare accordingly.
Solid business acumen; experience interpreting and applying compliance and related policies to executive’s personal interests.
Demonstrated initiative and ability to work in a fast paced, changing environment.
High degree of integrity and the ability to recognize the requirements of confidentiality.
Ability to build and maintain outstanding relationships.
Does this sound like something you would be interested in?
If so, reply with your up-to-date Resume by e-mail highlighting your qualifications and your mailing address.
Our contact: resume(a)pplinvoices.info
Thank you!
4 years, 1 month
Staff Wanted
by linux-nvdimm@lists.01.org
Dear Job Seeker,
Position Name: Project Manager (Supply Chain);
Company: DSC Logistics
Functional area: Logistics Services;
Area of Interest: Logistics Services;
Salary: $98,000/year;
Job Offer Available: 15th August 2018;
Job Type: Permanent Position;
Location: USA/15 States (can be telecommute)
Travel Requirement: All in state
The Position: This position is in the area of Project Management.
You will manage all aspects of production planning and scheduling.
The position requires a manager who can manage projects in
different areas across the business such as procurement and become a liaison between company and our clients.
Experience/Skills Required:
- US citizen only!
- Bachelor Degree
- Highly proficient in MS software
- Ability to multi-task
- Excellent written and verbal skills
- Desired management experience in performance management.
If you are interested in the position, please respond with your CV and resume attached.
Our contact: cv(a)logistictravels.info
Thank you!
4 years, 1 month
[RFC PATCH 1/1] device-dax: check for vma range while dax_mmap.
by Zhang Yi
It should be prevent user map an illegal vma range which larger than
dax device phiscal resourse, as we don't have swap logic while page
faulting in dax device.
Applications, especailly qemu, map the /dev/dax for virtual nvdimm's
backend device, we defined the v-nvdimm label area at the end of mapped
rang. By using an illegal size that exceeds the physical resource of
/dev/dax, then it will triger qemu a signal fault while accessing these
label area.
Signed-off-by: Zhang Yi <yi.z.zhang(a)linux.intel.com>
---
drivers/dax/device.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index aff2c15..c9a50cd 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -177,6 +177,32 @@ static const struct attribute_group *dax_attribute_groups[] = {
NULL,
};
+static int check_vma_range(struct dev_dax *dev_dax, struct vm_area_struct *vma,
+ const char *func)
+{
+ struct device *dev = &dev_dax->dev;
+ struct resource *res;
+ unsigned long size;
+ int ret, i;
+
+ if (!dax_alive(dev_dax->dax_dev))
+ return -ENXIO;
+
+ size = vma->vm_end - vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT);
+ ret = -EINVAL;
+ for (i = 0; i < dev_dax->num_resources; i++) {
+ res = &dev_dax->res[i];
+ if (size > resource_size(res)) {
+ dev_info(dev, "%s: %s: fail, vma range is overflow\n",
+ current->comm, func);
+ ret = -EINVAL;
+ continue;
+ } else
+ return 0;
+ }
+ return ret;
+}
+
static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma,
const char *func)
{
@@ -465,6 +491,8 @@ static int dax_mmap(struct file *filp, struct vm_area_struct *vma)
*/
id = dax_read_lock();
rc = check_vma(dev_dax, vma, __func__);
+ if (!rc)
+ rc |= check_vma_range(dev_dax, vma, __func__);
dax_read_unlock(id);
if (rc)
return rc;
--
2.7.4
4 years, 1 month
Hello!
by linux-nvdimm@lists.01.org
Dear Job Seeker,
Position Name: Project Manager (Supply Chain);
Company: DSC Logistics
Functional area: Logistics Services;
Area of Interest: Logistics Services;
Salary: $98,000/year;
Job Offer Available: 15th August 2018;
Job Type: Permanent Position;
Location: USA/15 States (can be telecommute)
Travel Requirement: All in state
The Position: This position is in the area of Project Management.
You will manage all aspects of production planning and scheduling.
The position requires a manager who can manage projects in
different areas across the business such as procurement and become a liaison between company and our clients.
Experience/Skills Required:
- US citizen only!
- Bachelor Degree
- Highly proficient in MS software
- Ability to multi-task
- Excellent written and verbal skills
- Desired management experience in performance management.
If you are interested in the position, please respond with your CV and resume attached.
Our contact: cv(a)logistictravels.info
Thank you!
4 years, 1 month
[PATCH] ACPI: nfit: check dcr immediately following its assignment codes
by Ocean He
From: Ocean He <hehy1(a)lenovo.com>
In commit 6697b2cf69d43632 ("nfit: fix multi-interface dimm handling,
acpi6.1 compatibility"), the check codes of dcr were just following its
assignment codes. But they were separated by commit ad9ac5e1957531a8
("nfit: always associate flush hints").
Just change the check codes back to original position, without function
change.
Signed-off-by: Ocean He <hehy1(a)lenovo.com>
---
drivers/acpi/nfit/core.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 7c47900..c9e4c9a 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -1078,6 +1078,12 @@ static int __nfit_mem_init(struct acpi_nfit_desc *acpi_desc,
break;
}
+ if (dcr && !nfit_mem->dcr) {
+ dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n",
+ spa->range_index, dcr);
+ return -ENODEV;
+ }
+
list_for_each_entry(nfit_flush, &acpi_desc->flushes, list) {
struct acpi_nfit_flush_address *flush;
u16 i;
@@ -1101,12 +1107,6 @@ static int __nfit_mem_init(struct acpi_nfit_desc *acpi_desc,
break;
}
- if (dcr && !nfit_mem->dcr) {
- dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n",
- spa->range_index, dcr);
- return -ENODEV;
- }
-
if (type == NFIT_SPA_DCR) {
struct nfit_idt *nfit_idt;
u16 idt_idx;
--
1.8.3.1
4 years, 1 month
[ndctl PATCH v2] ndctl, list: add alarm_enable_<field> to list
by QI Fuli
This patch adds alarm_enable_<field> to list, so that users could check
if the "ndctl inject-smart --<field>-alarm=on/off" works well or not.
Signed-off-by: QI Fuli <qi.fuli(a)jp.fujitsu.com>
---
v1 -> v2:
remove the renaming for list items.
ndctl/util/json-smart.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/ndctl/util/json-smart.c b/ndctl/util/json-smart.c
index 6a1f294..e25483d 100644
--- a/ndctl/util/json-smart.c
+++ b/ndctl/util/json-smart.c
@@ -39,34 +39,61 @@ static void smart_threshold_to_json(struct ndctl_dimm *dimm,
unsigned int temp;
double t;
+ jobj = json_object_new_boolean(true);
+ if (jobj)
+ json_object_object_add(jhealth,
+ "alarm_enable_media_temperature", jobj);
temp = ndctl_cmd_smart_threshold_get_temperature(cmd);
t = ndctl_decode_smart_temperature(temp);
jobj = json_object_new_double(t);
if (jobj)
json_object_object_add(jhealth,
"temperature_threshold", jobj);
+ } else {
+ jobj = json_object_new_boolean(false);
+ if (jobj)
+ json_object_object_add(jhealth,
+ "alarm_enable_media_temperature", jobj);
}
if (alarm_control & ND_SMART_CTEMP_TRIP) {
unsigned int temp;
double t;
+ jobj = json_object_new_boolean(true);
+ if (jobj)
+ json_object_object_add(jhealth,
+ "alarm_enable_ctrl_temperature", jobj);
temp = ndctl_cmd_smart_threshold_get_ctrl_temperature(cmd);
t = ndctl_decode_smart_temperature(temp);
jobj = json_object_new_double(t);
if (jobj)
json_object_object_add(jhealth,
"controller_temperature_threshold", jobj);
+ } else {
+ jobj = json_object_new_boolean(false);
+ if (jobj)
+ json_object_object_add(jhealth,
+ "alarm_enable_ctrl_temperature", jobj);
}
if (alarm_control & ND_SMART_SPARE_TRIP) {
unsigned int spares;
+ jobj = json_object_new_boolean(true);
+ if (jobj)
+ json_object_object_add(jhealth,
+ "alarm_enable_spares", jobj);
spares = ndctl_cmd_smart_threshold_get_spares(cmd);
jobj = json_object_new_int(spares);
if (jobj)
json_object_object_add(jhealth,
"spares_threshold", jobj);
+ } else {
+ jobj = json_object_new_boolean(false);
+ if (jobj)
+ json_object_object_add(jhealth,
+ "alarm_enable_spares", jobj);
}
out:
--
2.18.0
4 years, 1 month
[PATCH v3] ndctl, test: add a new unit test for max_available_extent namespace
by Masayoshi Mizuma
From: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
Add a new unit test to test max_available_extent namespace.
This feature is implemented by the following patches.
kernel side:
https://lists.01.org/pipermail/linux-nvdimm/2018-July/016731.html
https://lists.01.org/pipermail/linux-nvdimm/2018-July/016732.html
ndctl side:
https://lists.01.org/pipermail/linux-nvdimm/2018-July/017176.html
Signed-off-by: Masayoshi Mizuma <m.mizuma(a)jp.fujitsu.com>
---
test/Makefile.am | 3 ++-
test/max_available_extent_ns.sh | 46 +++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+), 1 deletion(-)
create mode 100755 test/max_available_extent_ns.sh
diff --git a/test/Makefile.am b/test/Makefile.am
index 8c55056..9af2464 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -22,7 +22,8 @@ TESTS =\
firmware-update.sh \
ack-shutdown-count-set \
rescan-partitions.sh \
- monitor.sh
+ monitor.sh \
+ max_available_extent_ns.sh
check_PROGRAMS =\
libndctl \
diff --git a/test/max_available_extent_ns.sh b/test/max_available_extent_ns.sh
new file mode 100755
index 0000000..1c7e7bf
--- /dev/null
+++ b/test/max_available_extent_ns.sh
@@ -0,0 +1,46 @@
+#!/bin/bash -Ex
+
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018, FUJITSU LIMITED. All rights reserved.
+
+rc=77
+
+. ./common
+
+trap 'err $LINENO' ERR
+
+check_min_kver "4.19" || do_skip "kernel $KVER may not support max_available_size"
+
+init()
+{
+ $NDCTL disable-region -b $NFIT_TEST_BUS0 all
+ $NDCTL zero-labels -b $NFIT_TEST_BUS0 all
+ $NDCTL enable-region -b $NFIT_TEST_BUS0 all
+}
+
+do_test()
+{
+ region=$($NDCTL list -b $NFIT_TEST_BUS0 -R -t pmem | jq -r 'sort_by(-.size) | .[].dev' | head -1)
+
+ available_sz=$($NDCTL list -r $region | jq -r .[].available_size)
+ size=$(( available_sz/4 ))
+
+ NS=()
+ for ((i=0; i<3; i++))
+ do
+ NS[$i]=$($NDCTL create-namespace -r $region -t pmem -s $size | jq -r .dev)
+ [[ -n ${NS[$i]} ]]
+ done
+
+ $NDCTL disable-namespace ${NS[1]}
+ $NDCTL destroy-namespace ${NS[1]}
+
+ $NDCTL create-namespace -r $region -t pmem
+}
+
+modprobe nfit_test
+rc=1
+init
+do_test
+_cleanup
+exit 0
--
2.18.0
4 years, 1 month
转发:如何规避供应链管理中的财务风险
by 赵女士
-------- 转发邮件信息 --------
发件人:asjxccv(a)pgus.net
发送日期:2018-8-9 1:19:34
收件人:linux-nvdimm(a)lists.01.org
采购必备的财税知识与技能训练
8月17-18日上海 瀚海明玉大酒店
【培训对象】供应链管理经理、采购经理、、物流经理、计划经理、供应商管理、库存管理人员等相关人士。
【课程费用】RMB4200元/人(包含:培训费、教材、午餐、茶点、发票)
报名咨询电话:021-31261580 手机:18890700600 (微信同号)赵先生
在线咨询QQ/邮箱:6983436 (报名请回复索取报名表)
课程背景
企业财务绩效通常是CEO和CFO最关注的考核指标,作为一名专业的供应链管理人员必须要了解我们的工作如何影响企业的财务指标,供应链管理的价值和绩效如何用CEO,CFO容易理解的财务语言表达,如何借助财务分析工具和知识帮助我们做出正确的采购决策,改善供应链管理绩效,规避供应链管理中的财务风险………
本课程在2天14个小时的课程,辅以1个桌面互动游戏,6个案例分析,非常有针对性的进行演练与说明,同时讲师结合自身10余年采购管理经验,使课程具有很高的实用性!
培训收益
Ø 掌握基本的财务知识,读懂常用财务报表
Ø 掌握三大主要的财务分析指标和改善方法
Ø 建立清晰的风险控制意识,强化现金流意识,提高资金运作效率
Ø 理解成本的分类和成本分析方法
Ø 掌握如何运用财务知识分析供应链成本
Ø 了解企业相关的税和优化方法
Ø 运用TCO模型分析产品生命周期的总成本
课程大纲
一、财务报表阅读和分析
l 财务分析目的和对象
l 三个主要的财务报表
l 资产负债表解读
l 收入表解读
l 现金流解读
l 关键财务绩效指标分析
l 偿付能力指标
l 运营效率指标
l 盈利能力指标
l 杜邦分析
l 现金流周转率--供应链管理绩效指标分析
l 财务模拟游戏
二、成本分析和管理
l 成本分类和成本结构分析
l 直接成本分析
l 间接成本分析
l 传统成本法
l 作业成本法
l 成本分析案例
三、财务知识在供应链中的运用
l 供应链成本分析
l 物流成本分析
l 资金成本分析
l 成本的牛鞭效应
l 量本利分析
l 采购和租赁分析
l 总拥有成本分析
l 案例—设备采购总成本分析
l 税和税务优化
l 税的种类和计算方法
l 税负优化案例分析
四、提升采购绩效,改善公司财务
l 采购绩效对财务指标的影响
l 采购绩效制定和考核
l 采购相关指数解读和运用
案例分析
讲师介绍:顾闻知
某跨国集团资深采购经理
行业资质:
英国专业管理协会认证的专业培训师C.I.P.T
美国供应管理协会认证采购经理C.P.M.
摩托罗拉大学授权讲师
加拿大采购管理协会中国授权讲师
上海帕迪企业管理咨询有限公司特邀讲师
工作经历:
顾先生具有二十多年的500强跨国企业工作经验,服务的公司包括摩托罗拉,柯达公司,历任产品开发,供应商质量管理,资源开发,外包管理,战略成本经理,战略采购经理等职务。顾先生是摩托罗拉在亚洲外包(Outsourcing)业务的第一批管理人员,负责管理5亿美元的外包业务,他帮助建立了对外包供应商的成本管理体系,供应链改进流程,连续两年被评为公司优秀员工。
顾先生也是柯达亚太区的第一位战略成本经理,主导建立了采购成本分析数据库,成本分析模型,有效地帮助公司取得了2位数的成本降价,领导跨部门团队进行拆解分析,引入并推动战略成本管理理念在采购工作的应用。在担任亚太区战略采购经理期间,负责公司ODM业务的采购管理,开发ODM价格管理体系和市场咨讯系统。
风格与特点:
顾先生对采购成本分析、采购战略、采购外包管理方面有多年的实践经验和很深的见解,尤其对采购成本分析具有丰富的实战经验,课程中引入大量的实际项目案例,让学员能够开阔视野,深受启发;独到的见解、风趣的讲授,往往赢得了学员们的一致好评;
培训/咨询服务的客户:
联想手机,沈阳华晨宝马,国核工程,腾讯科技,新宇航空,惠而浦,罗莱家纺,海信容声,伊倍达电子,山特维克材料,森松化工,奥的斯电梯,飞利浦亚明,萨帕铝热,汉佰(南京)纺织品,江阴贝卡尔特,阿法拉伐,上海适达,通用磨坊,美卓造纸机械,艾欧史密斯,慧智科技,联合汽车,上海英格索兰,埃新斯新能源,惠氏营养品,鼎举(上海)软件,魏德米勒,艾默生贸易,中达电通,利乐包装,爱克发,复盛易利达
客户评价:内容很丰富,对新的价格分析的方式了解很多。
能够系统的了解采购活动中的财务知识,与实际工作相结合,比较实用
4 years, 1 month
Hello!
by jhqr@cpdns.net
Dear Job Seeker,
Position Name: Project Manager (Supply Chain);
Company: DSC Logistics
Functional area: Logistics Services;
Area of Interest: Logistics Services;
Salary: $98,000/year;
Job Offer Available: 15th August 2018;
Job Type: Permanent Position;
Location: USA/15 States (can be telecommute)
Travel Requirement: All in state
The Position: This position is in the area of Project Management.
You will manage all aspects of production planning and scheduling.
The position requires a manager who can manage projects in
different areas across the business such as procurement and become a liaison between company and our clients.
Experience/Skills Required:
- US citizen only!
- Bachelor Degree
- Highly proficient in MS software
- Ability to multi-task
- Excellent written and verbal skills
- Desired management experience in performance management.
If you are interested in the position, please respond with your CV and resume attached.
Our contact: resume(a)logistictravels.info
Thank you!
4 years, 1 month
[ndctl PATCHv2 1/2] ndctl: Create ndctl udev rules for dirty shutdown
by Keith Busch
This patch provides an ndctl udev rule and the program it runs. The rule
sends two ndctl commands to allow applications to manage unsafe shutdowns.
The first command acknowledges the shutdown. For nvdimms that support
this, the last shutdown status will remain set to its current status
until it is acknowledged.
The second command retrieves the unclean shutdown count (USC) and saves it
in a known location. Only root can directly access the health's shutdown
count, so we have to stash it somewhere accessible to non-privileged
users. A successful execution of the rule will write USC to the run time
tmpfs location. By default, the location will be set to:
/run/ndctl/nmem<X>/usc
A distro may change this location using the '--with-tmpfilesdir=[DIR]'.
Reading the file will report the count observed when the dimm was
added.
Signed-off-by: Keith Busch <keith.busch(a)intel.com>
---
v1 -> v2:
Merged to ndctl/pending
Used more generic names
Split the udev program actions, and save USC regardless of the outcome
of the first action
Removed rpm spec setting configure's tmpfilesdir
Use nmem<X> instead of dimm-id for runtime directory name
Update changelog
.gitignore | 1 +
Makefile.am | 3 +
configure.ac | 10 ++++
contrib/80-ndctl.rules | 3 +
ndctl.spec.in | 3 +
ndctl/Makefile.am | 5 ++
ndctl/ndctl-udev.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 172 insertions(+)
create mode 100644 contrib/80-ndctl.rules
create mode 100644 ndctl/ndctl-udev.c
diff --git a/.gitignore b/.gitignore
index 0baace4..f13a7ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ daxctl/lib/libdaxctl.pc
*.a
ndctl/lib/libndctl.pc
ndctl/ndctl
+ndctl/ndctl-udev
rhel/
sles/ndctl.spec
util/log.lo
diff --git a/Makefile.am b/Makefile.am
index e0c463a..7880eef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,9 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
dist_bashcompletion_DATA = contrib/ndctl
endif
+udevrulesdir = $(UDEVDIR)/rules.d
+dist_udevrules_DATA = contrib/80-ndctl.rules
+
noinst_LIBRARIES = libccan.a
libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/configure.ac b/configure.ac
index e242334..4441a44 100644
--- a/configure.ac
+++ b/configure.ac
@@ -164,8 +164,17 @@ AS_IF([test "x$with_systemd_unit_dir" != "xno"],
[AC_SUBST([systemd_unitdir], [$with_systemd_unit_dir])])
AM_CONDITIONAL([ENABLE_SYSTEMD_UNIT_DIR], [test "x$with_systemd_unit_dir" != "xno"])
+AC_ARG_WITH([tmpfilesdir],
+ [AS_HELP_STRING([--with-tmpfilesdir=DIR], [Directory for temporary runtime files])],
+ [tmpfilesdir=$withval],
+ [tmpfilesdir="/run"])
+
+UDEVDIR="$(pkg-config udev --variable=udevdir)"
+AC_SUBST([UDEVDIR])
+
my_CFLAGS="\
-D DEF_CONF_FILE='\"${sysconfdir}/ndctl/monitor.conf\"' \
+-D DEF_TMPFS_DIR='\"${tmpfilesdir}/ndctl\"' \
-Wall \
-Wchar-subscripts \
-Wformat-security \
@@ -207,6 +216,7 @@ AC_MSG_RESULT([
libdir: ${libdir}
includedir: ${includedir}
systemd-unit-dir: ${systemd_unitdir}
+ tmpfilesdir: ${tmpfilesdir}
compiler: ${CC}
cflags: ${CFLAGS}
diff --git a/contrib/80-ndctl.rules b/contrib/80-ndctl.rules
new file mode 100644
index 0000000..54788c4
--- /dev/null
+++ b/contrib/80-ndctl.rules
@@ -0,0 +1,3 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="add", KERNEL=="nmem*", RUN+="ndctl-udev $kernel"
diff --git a/ndctl.spec.in b/ndctl.spec.in
index 17152c1..062aafb 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -110,6 +110,7 @@ make check
%postun -n DAX_LNAME -p /sbin/ldconfig
%define bashcompdir %(pkg-config --variable=completionsdir bash-completion)
+%define udevdir %(pkg-config --variable=udevdir udev)
%files
%defattr(-,root,root)
@@ -119,6 +120,8 @@ make check
%{bashcompdir}/
%{_sysconfdir}/ndctl/monitor.conf
%{_unitdir}/ndctl-monitor.service
+%{_udevrulesdir}/80-ndctl.rules
+%{udevdir}/ndctl-udev
%files -n daxctl
%defattr(-,root,root)
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 0f9bb43..4b44294 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -51,3 +51,8 @@ EXTRA_DIST += $(monitor_config_file)
if ENABLE_SYSTEMD_UNIT_DIR
systemd_unit_DATA = ndctl-monitor.service
endif
+
+ndctl_udevdir = $(UDEVDIR)
+ndctl_udev_PROGRAMS = ndctl-udev
+ndctl_udev_SOURCES = ndctl-udev.c
+ndctl_udev_LDADD = lib/libndctl.la
diff --git a/ndctl/ndctl-udev.c b/ndctl/ndctl-udev.c
new file mode 100644
index 0000000..2b4d067
--- /dev/null
+++ b/ndctl/ndctl-udev.c
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018 Intel Corporation. All rights reserved. */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <ndctl/libndctl.h>
+
+/**
+ * mkdir_p
+ *
+ * Copied from util-linux lib/fileutils.c
+ */
+static int mkdir_p(const char *path, mode_t mode)
+{
+ char *p, *dir;
+ int rc = 0;
+
+ if (!path || !*path)
+ return -EINVAL;
+
+ dir = p = strdup(path);
+ if (!dir)
+ return -ENOMEM;
+
+ if (*p == '/')
+ p++;
+
+ while (p && *p) {
+ char *e = strchr(p, '/');
+ if (e)
+ *e = '\0';
+ if (*p) {
+ rc = mkdir(dir, mode);
+ if (rc && errno != EEXIST)
+ break;
+ rc = 0;
+ }
+ if (!e)
+ break;
+ *e = '/';
+ p = e + 1;
+ }
+
+ free(dir);
+ return rc;
+}
+
+static struct ndctl_dimm *find_dimm(struct ndctl_ctx *ctx, const char *devname)
+{
+ struct ndctl_bus *bus;
+ struct ndctl_dimm *dimm;
+
+ ndctl_bus_foreach(ctx, bus) {
+ ndctl_dimm_foreach(bus, dimm) {
+ if (strcmp(ndctl_dimm_get_devname(dimm), devname) == 0)
+ return dimm;
+ }
+ }
+ return NULL;
+}
+
+static void ack_shutdown(struct ndctl_dimm *dimm)
+{
+ struct ndctl_cmd *cmd;
+
+ cmd = ndctl_dimm_cmd_new_ack_shutdown_count(dimm);
+ if (!cmd)
+ return;
+ ndctl_cmd_submit(cmd);
+ ndctl_cmd_unref(cmd);
+}
+
+static void save_unsafe_shutdown_count(struct ndctl_dimm *dimm,
+ const char *devname)
+{
+ char *path, *usc, count[16];
+ unsigned int shutdown;
+ struct ndctl_cmd *cmd;
+ int fd;
+
+ cmd = ndctl_dimm_cmd_new_smart(dimm);
+ if (!cmd)
+ return;
+
+ if (ndctl_cmd_submit(cmd))
+ goto unref_cmd;
+
+ shutdown = ndctl_cmd_smart_get_shutdown_count(cmd);
+ if (shutdown == UINT_MAX)
+ goto unref_cmd;
+
+ if (asprintf(&path, DEF_TMPFS_DIR "/%s", devname) < 0)
+ goto unref_cmd;
+
+ if (mkdir_p(path, 0755))
+ goto free_path;
+
+ if (asprintf(&usc, "%s/usc", path) < 0)
+ goto free_path;
+
+ fd = open(usc, O_WRONLY | O_CREAT, 0644);
+ if (fd < 0)
+ goto free_usc;
+
+ if (snprintf(count, sizeof(count), "%u\n", shutdown) < 0)
+ goto free_usc;
+
+ if (write(fd, count, strlen(count)) < 0)
+ goto free_usc;
+ free_usc:
+ free(usc);
+ free_path:
+ free(path);
+ unref_cmd:
+ ndctl_cmd_unref(cmd);
+}
+
+int main(int argc, char *argv[])
+{
+ struct ndctl_ctx *ctx;
+ struct ndctl_dimm *dimm = NULL;
+ const char *devname;
+
+ if (argc < 2)
+ return EINVAL;
+
+ devname = argv[1];
+ if (ndctl_new(&ctx))
+ return ENOMEM;
+
+ dimm = find_dimm(ctx, devname);
+ if (!dimm)
+ return ENODEV;
+
+ ack_shutdown(dimm);
+ save_unsafe_shutdown_count(dimm, devname);
+
+ ndctl_unref(ctx);
+ return 0;
+}
--
2.14.4
4 years, 1 month