2016年9月

我们很高兴地宣布你现在可以在 Azure SQL 中查询及存储关系型数据或者 JSON 了、Azure SQL 数据库提供了读取 JSON 文本数据的简单的内置函数,将 JSON 文本转化成表,以及将表的数据转化成 JSON。

你可以使用 JSON 函数来从 JSON 文本中提取值(JSON\_VALUE)、提取对象(JSON\_QUERY), 更新JSON 中的值(JSON\_MODIFY),并且验证 JSON 文本的正确性(ISJSON)。OPENJSON 函数让你可以将 JSON 文本转化成表结构。最后,JSON 功能函数可以让你很简单地从 SQL 查询中使用 FOR JSON 从句来获得 JSON 文本结果。

你可以用 JSON 做什么?

Azure SQL 数据库中的 JSON 可以让您构建并与现代 web、移动设备和 HTML5/单页应用、诸如 Azure DocumentDB 等包含 JSON 格式化数据的 NoSQL 存储等交换数据,分析来自不同系统和服务的日志和消息。现在你可以轻易地将 Azure SQL 数据库与任何使用使用 JSON 的服务集成。

轻易地开放数据给现代框架和服务

你有没有在使用诸如 REST 或者 Azure App 使用 JSON 来交换数据的服务?你有使用诸如 AngularJS、ReactJS、D3 或者 JQuery 等使用 JSON 的组件或框架么?使用新的 JSON 功能函数,你可以轻易地格式化存储在 Azure SQL 数据库中的数据,并将它用在任何现代服务或者应用中。

轻松采集 JSON 数据

你有在使用移动设备、传感器、如 Azure Stream Analytics 或者 Insight 这样产生 JSON 的服务、如 Azure DocumentDB 或者 MongoDB 这样存储 JSON 的系统么?你需要在 Azure SQL 数据中使用熟悉的 SQL 语句来查询并分析 JSON 数据么?现在你可以轻松采集 JSON 数据并存储到 Azure SQL 数据库中,并且可以使用任何 Azure SQL 数据库支持的语言或者工具来查询和分析加载的数据。

简化你的数据模型

你需要同时存储及查询数据库中关系型及半结构化的数据么?你需简化像 NoSQL 平台下的数据模型么?现在你可以在一张表中同时存储结构化数据及非结构化数据了。在 Azure SQL 数据库中,你可以同时从关系型及 NoSQL 的世界中使用最好的方法来调整你的数据模型。Azure SQL 数据库让你可以使用 Transact-SQL 语言来查询关系及 JSON 数据。程序和工具将不会在从表中取出的值及 JSON 文本中提取的值看出差别。

下一步

要学习如何在你的应用中集成 JSON,查看我们的开始学习页面或者 Channel 9的视频。要了解不同的情景下如何集成 JSON,观看 Channel 9 的视频或者在这些 JSON 分类文章中查找你感兴趣的使用情景。

我们将持续增加新的 JSON 特性并让 JSON 支持的更好。请敬请关注。


via: https://azure.microsoft.com/en-us/blog/json-support-is-generally-available-in-azure-sql-database/

作者:Jovan Popovic 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

开源正在走向胜利,虽然这一天或许会来的晚一点,但是开源终将胜利。在网络安全社区里,尽管许多公司以商业软件的方式牢牢把握着自己的代码不放,但是也有很多安全方面的开源项目可供专业的安全人员使用。

搜寻这些安全相关的开源软件最好的地方显然是 GitHub。你可以使用该网站上的搜索功能来找到这些有用的工具,但是有一个地方可以让你找到那些安全方面最流行的项目,那就是 GitHub 的展示区,可能知道它的人不多。

从 2014 年开始,GitHub 展示区就会按照分类陈列这些最流行的项目。在展示区中,项目以其所获得的 星标数 stars 排名,这个列表会不断更新当前最流行的项目。

展示区包含的“安全”分类中包含了 24 个项目,这里我们列出了在 GitHub 上排名前十的安全项目。

1. osquery - 来自 Facebook

osquery 将操作系统表示为一个高性能的关系型数据库。这可以让你通过基于 SQL 的查询来获取操作系统数据。通过 osquery,将运行中的进程、加载的内核模块、打开的网络连接、浏览器插件、硬件事件或文件哈希等抽象为 SQL 数据表。

2. Metasploit Framework - 来自 Rapid7

Metasploit Framework 是一个针对远程目标主机开发和执行漏洞利用代码的工具。

3. Infer - 来自 Facebook

Facebook Infer 是一个静态分析工具。用它来分析 Objective-C、Java 或 C 代码,可以列出其中潜在的缺陷。在代码上传到手机设备之前,可以用 Infer 来找到那些致命缺陷,可以防止出现崩溃或性能下降。

4. Brakeman - 来自 PresidentBeef

Brakeman 是一个开源的静态分析工具,它可以检查 Ruby on Rails 应用的安全漏洞。

5. Radare2 - 来自 Radare 项目

Radare 是一个取证工具,是一个可编程的命令行十六进制编辑器,可以打开磁盘文件。它也支持二进制分析、反汇编代码、调试程序、连接到远程 gdb 服务器等等功能。

6. OS X Auditor - 来自 Jean-Philippe Teissier

OS X Auditor 是一个自由的 Mac OS X 计算机取证工具,它可以解析各种类型的文件,获取其中的可疑内容。

7. BeEF - 来自 BeEF 项目

BeEF 简单的来说就是一个 浏览器利用框架 Browser Exploitation Framework 。它是一个针对浏览器的脆弱性测试工具。

8. Cuckoo - 来自 Cuckoo Sandbox 项目

Cuckoo Sandbox 是一个自动的恶意软件动态分析系统。简单的来说,就是你可以将任何可疑的文件丢给它,只需要几秒钟,Cuckoo 就可以给出在隔离的环境中执行的大致结果。

9. Scumblr - 来自 Netflix

Scumblr 是一个 Web 应用,它可以周期性地进行检查,并根据检查结果采取不同的处置方法。

10. Moloch - 来自 AOL

Moloch 是一个开源的、大规模的,抓包、索引并存储进数据库的系统。它提供了一个简单的 Web 界面,可以用来查看、检索和导出所捕获的数据包。它支持 API,可以直接下载 PCAP 数据和 JSON 格式的会话数据。Moloch 并不是用来替换 IDS 的,而是用来配合它们以标准的 PCAP 格式存储并索引所有的网络数据,从而可以快速访问。Moloch 可以跨系统部署,并可以处理高达每秒 10 Gb 的流量。

以上就是现在 GitHub 上最流行的安全相关的开源项目。你可以经常去展示区看看有无新的流行项目出现。

由于 2016 年 2 月 2 号开始启用了新的 LFCS 考试要求,我们在已经发表的 LFCS 系列 基础上增加了一些必要的主题。为了准备考试,同时也建议你看看 LFCE 系列 文章。

第十四讲: 监控 Linux 进程并为每个用户设置进程限制

每个 Linux 系统管理员都应该知道如何验证硬件、资源和主要进程的完整性和可用性。另外,基于每个用户设置资源限制也是其中一项必备技能。

在这篇文章中,我们会介绍一些能够确保系统硬件和软件正常工作的方法,这些方法能够避免潜在的会导致生产环境下线或钱财损失的问题发生。

报告 Linux 进程统计信息

你可以使用 mpstat 单独查看每个处理器或者系统整体的活动,可以是每次一个快照或者动态更新。

为了使用这个工具,你首先需要安装 sysstat

# yum update && yum install sysstat              [基于 CentOS 的系统]
# aptitutde update && aptitude install sysstat   [基于 Ubuntu 的系统]
# zypper update && zypper install sysstat        [基于 openSUSE 的系统]

你可以在 在 Linux 中学习 Sysstat 和其中的工具 mpstat、pidstat、iostat 和 sar 了解更多和 sysstat 和其中的工具相关的信息。

安装完 mpstat 之后,就可以使用它生成处理器统计信息的报告。

你可以使用下面的命令每隔 2 秒显示所有 CPU(用 -P ALL 表示)的 CPU 利用率(-u),共显示 3 次。

# mpstat -P ALL -u 2 3

示例输出:

Linux 3.19.0-32-generic (tecmint.com)   Wednesday 30 March 2016     _x86_64_    (4 CPU)

11:41:07  IST  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11:41:09  IST  all    5.85    0.00    1.12    0.12    0.00    0.00    0.00    0.00    0.00   92.91
11:41:09  IST    0    4.48    0.00    1.00    0.00    0.00    0.00    0.00    0.00    0.00   94.53
11:41:09  IST    1    2.50    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   97.00
11:41:09  IST    2    6.44    0.00    0.99    0.00    0.00    0.00    0.00    0.00    0.00   92.57
11:41:09  IST    3   10.45    0.00    1.99    0.00    0.00    0.00    0.00    0.00    0.00   87.56

11:41:09  IST  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11:41:11  IST  all   11.60    0.12    1.12    0.50    0.00    0.00    0.00    0.00    0.00   86.66
11:41:11  IST    0   10.50    0.00    1.00    0.00    0.00    0.00    0.00    0.00    0.00   88.50
11:41:11  IST    1   14.36    0.00    1.49    2.48    0.00    0.00    0.00    0.00    0.00   81.68
11:41:11  IST    2    2.00    0.50    1.00    0.00    0.00    0.00    0.00    0.00    0.00   96.50
11:41:11  IST    3   19.40    0.00    1.00    0.00    0.00    0.00    0.00    0.00    0.00   79.60

11:41:11  IST  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11:41:13  IST  all    5.69    0.00    1.24    0.00    0.00    0.00    0.00    0.00    0.00   93.07
11:41:13  IST    0    2.97    0.00    1.49    0.00    0.00    0.00    0.00    0.00    0.00   95.54
11:41:13  IST    1   10.78    0.00    1.47    0.00    0.00    0.00    0.00    0.00    0.00   87.75
11:41:13  IST    2    2.00    0.00    1.00    0.00    0.00    0.00    0.00    0.00    0.00   97.00
11:41:13  IST    3    6.93    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   92.57

Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all    7.71    0.04    1.16    0.21    0.00    0.00    0.00    0.00    0.00   90.89
Average:       0    5.97    0.00    1.16    0.00    0.00    0.00    0.00    0.00    0.00   92.87
Average:       1    9.24    0.00    1.16    0.83    0.00    0.00    0.00    0.00    0.00   88.78
Average:       2    3.49    0.17    1.00    0.00    0.00    0.00    0.00    0.00    0.00   95.35
Average:       3   12.25    0.00    1.16    0.00    0.00    0.00    0.00    0.00    0.00   86.59

要查看指定的 CPU(在下面的例子中是 CPU 0),可以使用:

# mpstat -P 0 -u 2 3

示例输出:

Linux 3.19.0-32-generic (tecmint.com)   Wednesday 30 March 2016     _x86_64_    (4 CPU)

11:42:08  IST  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
11:42:10  IST    0    3.00    0.00    0.50    0.00    0.00    0.00    0.00    0.00    0.00   96.50
11:42:12  IST    0    4.08    0.00    0.00    2.55    0.00    0.00    0.00    0.00    0.00   93.37
11:42:14  IST    0    9.74    0.00    0.51    0.00    0.00    0.00    0.00    0.00    0.00   89.74
Average:       0    5.58    0.00    0.34    0.85    0.00    0.00    0.00    0.00    0.00   93.23

上面命令的输出包括这些列:

  • CPU: 整数表示的处理器号或者 all 表示所有处理器的平均值。
  • %usr: 运行在用户级别的应用的 CPU 利用率百分数。
  • %nice: 和 %usr 相同,但有 nice 优先级。
  • %sys: 执行内核应用的 CPU 利用率百分比。这不包括用于处理中断或者硬件请求的时间。
  • %iowait: 指定(或所有)CPU 的空闲时间百分比,这表示当前 CPU 处于 I/O 操作密集的状态。更详细的解释(附带示例)可以查看这里
  • %irq: 用于处理硬件中断的时间所占百分比。
  • %soft: 和 %irq 相同,但是是软中断。
  • %steal: 虚拟机非自主等待(时间片窃取)所占时间的百分比,即当虚拟机在竞争 CPU 时所从虚拟机管理程序那里“赢得”的时间。应该保持这个值尽可能小。如果这个值很大,意味着虚拟机正在或者将要停止运转。
  • %guest: 运行虚拟处理器所用的时间百分比。
  • %idle: CPU 没有运行任何任务所占时间的百分比。如果你观察到这个值很小,意味着系统负载很重。在这种情况下,你需要查看详细的进程列表、以及下面将要讨论的内容来确定这是什么原因导致的。

运行下面的命令使处理器处于极高负载,然后在另一个终端执行 mpstat 命令:

# dd if=/dev/zero of=test.iso bs=1G count=1
# mpstat -u -P 0 2 3
# ping -f localhost # Interrupt with Ctrl + C after mpstat below completes
# mpstat -u -P 0 2 3

最后,和 “正常” 情况下 mpstat 的输出作比较:

Linux 处理器相关统计信息报告

正如你在上面图示中看到的,在前面两个例子中,根据 %idle 的值可以判断 CPU 0 负载很高。

在下一部分,我们会讨论如何识别资源饥饿型进程,如何获取更多和它们相关的信息,以及如何采取恰当的措施。

Linux 进程报告

我们可以使用有名的 ps 命令,用 -eo 选项(根据用户定义格式选中所有进程) 和 --sort 选项(指定自定义排序顺序)按照 CPU 使用率排序列出进程,例如:

# ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu

上面的命令只会显示 PIDPPID、和进程相关的命令、 CPU 使用率以及 RAM 使用率,并按照 CPU 使用率降序排序。创建 .iso 文件的时候运行上面的命令,下面是输出的前面几行:

根据 CPU 使用率查找进程

一旦我们找到了感兴趣的进程(例如 PID=2822 的进程),我们就可以进入 /proc/PID(本例中是 /proc/2822) 列出目录内容。

这个目录就是进程运行的时候保存多个关于该进程详细信息的文件和子目录的目录。

例如:

  • /proc/2822/io 包括该进程的 IO 统计信息(IO 操作时的读写字符数)。
  • /proc/2822/attr/current 显示了进程当前的 SELinux 安全属性。
  • /proc/2822/cgroup 如果启用了 CONFIGCGROUPS 内核设置选项,这会显示该进程所属的控制组(简称 cgroups),你可以使用下面命令验证是否启用了 CONFIGCGROUPS:
# cat /boot/config-$(uname -r) | grep -i cgroups

如果启用了该选项,你应该看到:

CONFIG_CGROUPS=y

根据 红帽企业版 Linux 7 资源管理指南 第一到四章的内容、openSUSE 系统分析和调优指南 第九章、Ubuntu 14.04 服务器文档 Control Groups 章节,你可以使用 cgroups 管理每个进程允许使用的资源数目。

/proc/2822/fd 这个目录包含每个打开的描述进程的文件的符号链接。下面的截图显示了 tty1(第一个终端) 中创建 .iso 镜像进程的相关信息:

查找 Linux 进程信息

上面的截图显示 stdin(文件描述符 0)、stdout(文件描述符 1)、stderr(文件描述符 2) 相应地被映射到 /dev/zero/root/test.iso/dev/tty1

更多关于 /proc 信息的可以查看 Kernel.org 维护的 “/proc 文件系统” 和 Linux 开发者手册。

在 Linux 中为每个用户设置资源限制

如果你不够小心、让任意用户使用不受限制的进程数,最终你可能会遇到意外的系统关机或者由于系统进入不可用的状态而被锁住。为了防止这种情况发生,你应该为用户可以启动的进程数目设置上限。

你可以在 /etc/security/limits.conf 文件末尾添加下面一行来设置限制:

*       hard    nproc   10

第一个字段可以用来表示一个用户、组或者所有人(*), 第二个字段强制限制可以使用的进程数目(nproc) 为 10。退出并重新登录就可以使设置生效。

然后,让我们来看看非 root 用户(合法用户或非法用户) 试图引起 shell fork 炸弹 (参见 WiKi) 时会发生什么。如果我们没有设置限制, shell fork 炸弹会无限制地启动函数的两个实例,然后无限循环地复制任意一个实例。最终导致你的系统卡死。

但是,如果使用了上面的限制,fort 炸弹就不会成功,但用户仍然会被锁在外面直到系统管理员杀死相关的进程。

运行 Shell Fork 炸弹

提示limits.conf 文件中可以查看其它 ulimit 可以更改的限制。

其它 Linux 进程管理工具

除了上面讨论的工具, 一个系统管理员还可能需要:

a) 通过使用 renice 调整执行优先级(系统资源的使用)。这意味着内核会根据分配的优先级(众所周知的 “niceness”,它是一个范围从 -2019 的整数)给进程分配更多或更少的系统资源。

这个值越小,执行优先级越高。普通用户(而非 root)只能调高他们所有的进程的 niceness 值(意味着更低的优先级),而 root 用户可以调高或调低任何进程的 niceness 值。

renice 命令的基本语法如下:

# renice [-n] <new priority> <UID, GID, PGID, or empty> identifier

如果 new priority 后面的参数没有(为空),默认就是 PID。在这种情况下,PID=identifier 的进程的 niceness 值会被设置为 <new priority>

b) 需要的时候中断一个进程的正常执行。这也就是通常所说的“杀死”进程。实质上,这意味着给进程发送一个信号使它恰当地结束运行并以有序的方式释放任何占用的资源。

按照下面的方式使用 kill 命令杀死进程

# kill PID

另外,你也可以使用 pkill 结束指定用户(-u)、指定组(-G) 甚至有共同的父进程 ID (-P) 的所有进程。这些选项后面可以使用数字或者名称表示的标识符。

# pkill [options] identifier

例如:

# pkill -G 1000

会杀死组 GID=1000 的所有进程。而

# pkill -P 4993 

会杀死 PPID 是 4993 的所有进程。

在运行 pkill 之前,先用 pgrep 测试结果、或者使用 -l 选项列出进程名称是一个很好的办法。它需要和 pkill 相同的参数、但是只会返回进程的 PID(而不会有其它操作),而 pkill 会杀死进程。

# pgrep -l -u gacanepa

用下面的图片说明:

在 Linux 中查找用户运行的进程

总结

在这篇文章中我们探讨了一些监控资源使用的方法,以便验证 Linux 系统中重要硬件和软件组件的完整性和可用性。

我们也学习了如何在特殊情况下采取恰当的措施(通过调整给定进程的执行优先级或者结束进程)。

我们希望本篇中介绍的概念能对你有所帮助。如果你有任何疑问或者评论,可以使用下面的联系方式联系我们。


via: http://www.tecmint.com/monitor-linux-processes-and-set-process-limits-per-user/

作者:Gabriel Cánepa 译者:ictlyh 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

大家都说所有的关系都需要经历两年、七年甚至十年的磨砺。我忘了是谁说的这句话,但肯定有人在几年前这么跟我说过。

下周是我来悉尼两周年,所以我想现在正是我写这篇文章的好时候。

去年五月份参加 I/O 年会的时候,我遇到了亚斯曼女士,她十分漂亮。她向我询问我是如何成长为一名安卓开发者的,当我说完我的经历时,她认为我应该写个博客记下来。所以亚斯曼,如你所愿,虽然迟了点,但好过没做。;)

故事的开始

如果有件事我可能希望你知道,那就是我发现自己有选择困难症。你最好的朋友是谁?你最喜欢的食物是什么?你应该给你的玩具熊猫命名吗?我连这些问题都不知道该怎么回答才好。所以你可以想象到,16 岁的、即将高中毕业的我对于专业选择根本就没有任何想法。那我最初申请的大学是?在交表给注册员前,我在她面前逐字掂量着写下这个打算申请的专业(商业经济学)。

可我最后去了另外一间学校,就读电子与通信工程。大一时我有一门计算机编程课程。但我很讨厌编程,十分地讨厌。关于编程的一切我都一无所知。我曾发誓再也不要写代码了。

我大学毕业后的第一份工作是在英特尔做产品工程师并在那呆了两年。我很迷茫,无所适从,整天长时间工作。这在我意料之中,身为成年人难道不该努力工作吗?可之后菲律宾的半导体行业开始呈现颓势,大批工厂纷纷倒闭,以前由我们维护一些产品被转移到其他分公司。我便决定去找另一份工作而不是等着被裁员,因为被裁员后我都不知道自己多久才能找到另一份工作。

现在呢?

我想留在城市里找到一份工作,但我不想呆在正在没落的半导体行业里了。但话说回来,我又不知道该做什么好。对了,我可是拿了毕业证书的工程师,所以从技术上来说我可以在电信运营商或电视台找到工作。可这种时候,如果想入职电信运营商,我应该在大学毕业之际就去他们那实习,这样更容易被录用。可惜我没有,所以我放弃了这个想法。虽然有很多软件开发人员的招聘信息,但我讨厌编程,所以我真的不知道怎么做才好。

接下来是我第一个幸运的机遇,我很幸运地遇到了信任我的上司,我也和她坦诚了我什么都不会。之后我不得不边工作边学习,一开始这个过程很漫长。无需多言,我在这份工作上学到了很多,也结识了很多很好的人,与我一起的是一群很厉害的同事(我们曾开发出安装在 SIM 卡上的 APP)。但更重要的是我开始踏上了软件开发的征途。

最后我做得更多是一些公司的琐事(十分无聊)直到项目完结。换句话说,我总在是在办公室里闲逛并坐等发薪。之后我发现这确实是在浪费时间,2009 年的时候,我不停地接触到关于谷歌的新系统 Android 的消息,并得知它的 SDK 已经公布!是时候尝试一波了。于是我安装了所有相关软件并着手 Android 开发。

事情变得有趣了

所以现在我能够构建一个在运行在仿真器的 Hello World 应用,在我看来意味着我有胜任安卓开发工作的能力。我加入了一个创业公司,并且再次坦诚我不知道该怎么做,我只是接触过一些;但如果你们愿意付薪水给我继续尝试,我们就可以成为朋友。然后我很幸运地遇到另一个机遇。

那时成为开发者是一件令人欣喜的事。StackOverflow 上的 Android 开发社区非常小,我们都在相互交流学习,说真的,我认为里面的所有人都很友好、很豪迈(注 1)!

我最后去了一家企业,这家企业的移动开发团队在马尼拉、悉尼、纽约都设有办公地点。而我是马尼拉办公地点的第一个安卓开发人员,但那时我很习惯,并没有在意。

在那里我认识了最后令我永远感激的引荐我参与 Domain 项目的人。Domain 项目不管在个人或职业上对我来说都意味深重。我和一支很有才华的团队一起共事,也从没见过一个公司能如此执着于一款产品。Domain 让我实现了参加 I/O 年会的梦。与他们共事后我懂得了很多之前没想到的可爱特性(注 2)。这是又一个幸运的机遇,我是说最大限度地利用它。

然后呢?

我想说的是,虽然这些年都在晃荡,但至少我很诚实,对吧?如上就是我所学到的全部东西。说一句「我不懂」没什么可怕的。有时候我们是该装懂,但更多时候我们需要坦诚地接受这样一个事实:我们还不懂。

别害怕尝试新事物,不管它让你感觉多害怕。我知道说比做简单。但总有一些东西能让你鼓起勇气动手去尝试的(注3)。Lundagin mo, baby!(LCTT 译注:一首歌名)

注 1: 我翻阅着以前在 StackOverflow 提的问题,认真想想,如果现在我问他们这些,估计会收到很多「你是谁啊,傻瓜」的评论。我不知道是不是因为我老了,而且有些愤世妒俗。但关键是,我们有缘在同一个社区中,所以大家相互之间友善些,好吗?

注 2: 这一点写在另一篇文章里了。

注 3: 我还清晰地记得第一次申请 Android 开发职位的情形:我写完求职信后又通读了一遍,提交前鼠标在发送按钮上不断徘徊,深呼吸之后我趁改变主意之前把它发出去了。


via: http://www.zdominguez.com/2016/08/winging-it-how-i-got-to-be-android-dev.html

作者:Zarah Dominguez 译者:JianhuanZhuo 校对:PurlingNayuki

本文由 LCTT 原创编译,Linux中国 荣誉推出

由于 LFCS 考试需求的变动已于 2016 年 2 月 2 日生效,因此我们向 LFCS 系列 添加了一些必要的话题。为了准备认证考试,我们也强烈推荐你去看看 LFCE 系列

LFCS 系列第十三讲:配置并排除 Grub 引导加载程序故障。

本文将会向你介绍 GRUB 的知识,并会说明你为什么需要一个引导加载程序,以及它是如何给系统增加功能的。

Linux 引导过程 是从你按下你的电脑电源键开始,直到你拥有一个全功能的系统为止,整个过程遵循着这样的主要步骤:

    1. 一个叫做 POST上电自检)的过程会对你的电脑硬件组件做全面的检查。
    1. POST 完成后,它会把控制权转交给引导加载程序,接下来引导加载程序会将 Linux 内核(以及 initramfs)加载到内存中并执行。
    1. 内核首先检查并访问硬件,然后运行初始化进程(主要以它的通用名 init 而为人熟知),接下来初始化进程会启动一些服务,最后完成系统启动过程。

在该系列的第七讲(“SysVinit、Upstart 和 Systemd”)中,我们介绍了现代 Linux 发行版使用的一些服务管理系统和工具。在继续学习之前,你可能想要回顾一下那一讲的知识。

GRUB 引导装载程序介绍

在现代系统中,你会发现有两种主要的 GRUB 版本(一种是有时被称为 GRUB Legacyv1 版本,另一种则是 v2 版本),虽说多数最新版本的发行版系统都默认使用了 v2 版本。如今,只有 红帽企业版 Linux 6 及其衍生系统仍在使用 v1 版本。

因此,在本指南中,我们将着重关注 v2 版本的功能。

不管 GRUB 的版本是什么,一个引导加载程序都允许用户:

  1. 通过指定使用不同的内核来修改系统的行为;
  2. 从多个操作系统中选择一个启动;
  3. 添加或编辑配置区块来改变启动选项等。

如今,GNU 项目负责维护 GRUB,并在它们的网站上提供了丰富的文档。当你在阅读这篇指南时,我们强烈建议你看下 GNU 官方文档

当系统引导时,你会在主控制台看到如下的 GRUB 画面。最开始,你可以根据提示在多个内核版本中选择一个内核(默认情况下,系统将会使用最新的内核启动),并且可以进入 GRUB 命令行模式(使用 c 键),或者编辑启动项(按下 e 键)。

GRUB 启动画面

你会考虑使用一个旧版内核启动的原因之一是之前工作正常的某个硬件设备在一次升级后出现了“怪毛病(acting up)”(例如,你可以参考 AskUbuntu 论坛中的这条链接)。

在启动时会从 /boot/grub/grub.cfg/boot/grub2/grub.cfg 文件中读取GRUB v2 的配置文件,而 GRUB v1 使用的配置文件则来自 /boot/grub/grub.conf/boot/grub/menu.lst。这些文件不应该直接手动编辑,而应通过 /etc/default/grub 的内容和 /etc/grub.d 目录中的文件来更新。

CentOS 7 上,当系统最初完成安装后,会生成如下的配置文件:

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

除了在线文档外,你也可以使用下面的命令查阅 GNU GRUB 手册:

# info grub

如果你对 /etc/default/grub 文件中的可用选项特别感兴趣的话,你可以直接查阅配置一节的帮助文档:

# info -f grub -n 'Simple configuration'

使用上述命令,你会发现 GRUB_TIMEOUT 用于设置启动画面出现和系统自动开始启动(除非被用户中断)之间的时间。当该变量值为 -1 时,除非用户主动做出选择,否则不会开始启动。

当同一台机器上安装了多个操作系统或内核后,GRUB_DEFAULT 就需要用一个整数来指定 GRUB 启动画面默认选择启动的操作系统或内核条目。我们既可以通过上述启动画面查看启动条目列表,也可以使用下面的命令:

在 CentOS 和 openSUSE 系统上

# awk -F\' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg

在 Ubuntu 系统上

# awk -F\' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg

如下图所示的例子中,如果我们想要使用版本为 3.10.0-123.el7.x86_64 的内核(第四个条目),我们需要将 GRUB_DEFAULT 设置为 3(条目从零开始编号),如下所示:

GRUB_DEFAULT=3

使用旧版内核启动系统

最后一个需要特别关注的 GRUB 配置变量是 GRUB_CMDLINE_LINUX,它是用来给内核传递选项的。我们可以在 内核变量文件man 7 bootparam 中找到能够通过 GRUB 传递给内核的选项的详细文档。

我的 CentOS 7 服务器上当前的选项是:

GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"

为什么你希望修改默认的内核参数或者传递额外的选项呢?简单来说,在很多情况下,你需要告诉内核某些由内核自身无法判断的硬件参数,或者是覆盖一些内核检测的值。

不久之前,就在我身上发生过这样的事情,当时我在自己已用了 10 年的老笔记本上尝试了衍生自 SlackwareVector Linux。完成安装后,内核并没有检测出我的显卡的正确配置,所以我不得不通过 GRUB 传递修改过的内核选项来让它工作。

另外一个例子是当你需要将系统切换到单用户模式以执行维护工作时。为此,你可以直接在 GRUB_CMDLINE_LINUX 变量中直接追加 single 并重启即可:

GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single"

编辑完 /etc/default/grub 之后,你需要运行 update-grub (在 Ubuntu 上)或者 grub2-mkconfig -o /boot/grub2/grub.cfg (在 CentOSopenSUSE 上)命令来更新 grub.cfg 文件(否则,改动会在系统启动时丢失)。

这条命令会处理早先提到的那些启动配置文件来更新 grub.cfg 文件。这种方法可以确保改动持久化,而在启动时刻通过 GRUB 传递的选项仅在当前会话期间有效。

修复 Linux GRUB 问题

如果你安装了第二个操作系统,或者由于人为失误而导致你的 GRUB 配置文件损坏了,依然有一些方法可以让你恢复并能够再次启动系统。

在启动画面中按下 c 键进入 GRUB 命令行模式(记住,你也可以按下 e 键编辑默认启动选项),并可以在 GRUB 提示中输入 help 命令获得可用命令:

修复 Linux 的 Grub 配置问题

我们将会着重关注 ls 命令,它会列出已安装的设备和文件系统,并且我们将会看看它查找到的东西。在下面的图片中,我们可以看到有 4 块硬盘(hd0hd3)。

貌似只有 hd0 已经分区了(msdos1 和 msdos2 可以证明,这里的 1 和 2 是分区号,msdos 则是分区方案)。

现在我们来看看能否在第一个分区 hd0msdos1)上找到 GRUB。这种方法允许我们启动 Linux,并且使用高级工具修复配置文件,或者如果有必要的话,干脆重新安装 GRUB:

# ls (hd0,msdos1)/

从高亮区域可以发现,grub2 目录就在这个分区:

查找 Grub 配置

一旦我们确信了 GRUB 位于 (hd0, msdos1),那就让我们告诉 GRUB 该去哪儿查找它的配置文件并指示它去尝试启动它的菜单:

set prefix=(hd0,msdos1)/grub2
set root=(hd0,msdos1)
insmod normal
normal

查找并启动 Grub 菜单

然后,在 GRUB 菜单中,选择一个条目并按下回车键以使用它启动。一旦系统成功启动后,你就可以运行 grub2-install /dev/sdX 命令修复问题了(将 sdX 改成你想要安装 GRUB 的设备)。然后启动信息将会更新,并且所有相关文件都会得到恢复。

# grub2-install /dev/sdX

其它更加复杂的情景及其修复建议都记录在 Ubuntu GRUB2 故障排除指南 中。该指南中阐述的概念对于其它发行版也是有效的。

总结

本文向你介绍了 GRUB,并指导你可以在何处找到线上和线下的文档,同时说明了如何面对由于引导加载相关的问题而导致系统无法正常启动的情况。

幸运的是,GRUB 是文档支持非常丰富的工具之一,你可以使用我们在文中分享的资源非常轻松地获取已安装的文档或在线文档。

你有什么问题或建议吗?请不要犹豫,使用下面的评论框告诉我们吧。我们期待着来自你的回复!


via: http://www.tecmint.com/configure-and-troubleshoot-grub-boot-loader-linux/

作者:Gabriel Cánepa 译者:ChrisLeeGit 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出

Andreia Gaita 在 OSCON 开源大会上发表了一个题为跨平台开发者的自白的演讲。她长期从事于开源工作,并且为 Mono 工程(LCTT 译注:一个致力于开创 .NET 在 Linux 上使用的开源工程)做着贡献,主要以 C#/C++ 开发。Andreia 任职于 GitHub,她的工作是专注构建 Visual Studio 的 GitHub 扩展管理器。

我在她发表演讲前就迫不及待的想要问她一些关于跨平台开发的事,问问她作为一名跨平台开发者在这 16 年之中学习到了什么。

在你开发跨平台代码中,你使用过的最简单的和最难的代码语言是什么?

我很少讨论某种语言的好坏,更多是讨论是那些语言有哪些库和工具。语言的编译器、解释器以及构建系统决定了用它们做跨平台开发的难易程度(或者它们是否可能做跨平台开发),可用的 UI 库和对本地系统的访问能力决定了与该操作系统集成的紧密程度。按照我的观点,我认为 C# 最适合完成跨平台开发工作。这种语言自身包括了允许快速的本地调用和精确的内存映射的功能,如果你希望你的代码能够与系统和本地函数库进行交互就需要这些功能。而当我需要非常特殊的系统功能时,我就会切换到 C 或者 C++。

你使用的跨平台开发工具或者抽象层有哪些?

我的大部分跨平台工作都是为其它需要开发跨平台应用的人开发工具、库和 绑定 binding ,一般是用 MONO/C# 和 C/C++。在抽象的层面我用的不多,更多是在 glib 库和 友元 friends 方面。大多数时候,我用 Mono 去完成各种跨平台应用的,包括 UI,或者偶然在游戏开发中用到 Unity3D 的部分。我经常使用 Electron(LCTT 译注:Atom 编辑器的兄弟项目,可以用 Electron 开发桌面应用)。

你接触过哪些构建系统?它们之间的区别是由于语言还是平台的不同?

我试着选择适合我使用的语言的构建系统。那样,就会很少遇到让我头疼的问题(希望如此)。它需要支持平台和体系结构间的选择、构建输出结果位置可以智能些(多个并行构建),以及易配置性等。大多数时候,我的项目会结合使用 C/C++ 和 C#,我要从同一源代码同时构建不同的配置环境(调试、发布、Windows、OSX、Linux、Android、iOS 等等),这通常需要为每个构建的输出结果选择带有不同参数的不同编译器。构建系统可以帮我做到这一切而不用让我(太)费心。我时常尝试着用不同的构建系统,看看有些什么新的变化,但是最终,我还是回到了使用 makefile 的情况,并结合使用 shell 和批处理脚本或 Perl 脚本来完成工作(因为如果我希望用户来构建我的软件,我还是最好选择一种到处都可以用的命令行脚本语言)。

你怎样平衡在这种使用统一的用户界面下提供原生的外观和体验的需求呢?

跨平台的用户界面的实现很困难。在过去几年中我已经使用了一些跨平台 GUI,并且我认为这些事情上并没有最优解。基本上有两种选择。你可以选择一个跨平台工具去做一个并不是完全适合你所有支持的平台的 UI,但是代码库比较小,维护成本比较低。或者你可以选择去开发针对平台的 UI,那样看起来更原生,集成的也更好,但是需要更大的代码库和更高的维护成本。这种决定完全取决于 APP 的类型、它有多少功能、你有多少资源,以及你要把它运行在多少平台上?

最后,我认为用户比较接受这种“一个 UI 打通关”了,就比如 Electron 框架。我有个 Chromium + C + C# 的框架侧项目,有一天我希望可以用 C# 构建 Electron 型的 app,这样的话我就可以做到两全其美了。

构建/打包系统的依赖性对你有影响吗 ?

我依赖的使用方面很保守,我被崩溃的 ABI(LCTT 译注:应用程序二进制接口)、冲突的符号、以及丢失的包等问题困扰了太多次。我决定我要针对的操作系统版本,并选择最低的公有部分来使问题最小化。通常这就意味着有五种不同的 Xcode 和 OSX 框架库,要在同样的机器上相应安装五种不同的 Visual Studio 版本,多种 clang(LCTT 译注:C语言、C++、Object-C、C++ 语言的轻量级编译器)和 gcc 版本,一系列的运行着各种发行版的虚拟机。如果我不能确定我要使用的操作系统的包的状态,我有时就会静态连接库,有时会子模块化依赖以确保它们一直可用。大多时候,我会避免这些很棘手的问题,除非我非常需要使用他们。

你使用持续集成(CI)、代码审查以及相关的工具吗?

基本每天都用。这是保持高效的唯一方式。我在一个项目中做的第一件事情是配置跨平台构建脚本,保证每件事尽可能自动化完成。当你面向多平台开发的时候,持续集成是至关重要的。没有人能在一个机器上构建各种平台的不同组合,并且一旦你的构建过程没有包含所有的平台,你就不会注意到你搞砸的事情。在一个共享式的多平台代码库中,不同的人拥有不同的平台和功能,所以保证质量的唯一的方法是跨团队代码审查结合持续集成和其他分析工具。这不同于其他的软件项目,如果不使用相关的工具就会面临失败。

你依赖于自动构建测试,或者倾向于在每个平台上构建并且进行本地测试吗?

对于不包括 UI 的工具和库,我通常使用自动构建测试。如果有 UI,两种方法我都会用到——针对已有的 GUI 工具的可靠的、可脚本化的 UI 自动化少到几乎没有,所以我要么我去针对我要跨我所支持的平台创建 UI 自动化工具,要么手动进行测试。如果一个项目使用了定制的 UI 库(比如说一个类似 Unity3D 的 OpenGL UI),开发可编程的自动化工具并自动化大多数工作就相当容易。不过,没有什么东西会像人一样双击就测试出问题。

如果你要做跨平台开发,你喜欢用跨编辑器的构建系统,比如在 Windows 上使用 Visual Studio,在 Linux 上使用 Qt Creator,在 Mac 上使用 XCode 吗?还是你更趋向于使用 Eclipse 这样的可以在所有平台上使用的单一平台?

我喜欢使用跨编辑器的构建系统。我更喜欢在不同的IDE上保存项目文件(这样可以使增加 IDE 变得更容易),通过使用构建脚本让 IDE 在它们支持的平台上去构建。对于一个开发者来说编辑器是最重要的工具,学习它们是需要花费时间和精力的,而它们是不可相互替代的。我有我自己喜欢的编辑器和工具,每个人也可以使用他们最喜爱的工具。

在跨平台开发的时候,你更喜欢使用什么样的编辑器、开发环境和 IDE 呢?

跨平台开发者被限制在只能选择可以在多数平台上工作的所共有的不多选择之一。我爱用 Visual Studio,但是我不能依赖它完成除 Windows 平台之外的工作(你可能不想让 Windows 成为你的主要的交叉编译平台),所以我不会使用它作为我的主要 IDE。即使可以,跨平台开发者的核心技能也是尽可能的了解和使用大量的平台。这就意味着必须很熟悉它们——使用该平台上的编辑器和库,了解这种操作系统及其适用场景、运行方式以及它的局限性等。做这些事情就需要头脑清醒(我的捷径是加强记忆),我必须依赖跨平台的编辑器。所以我使用 Emacs 和 Sublime。

你之前和现在最喜欢的跨平台项目是什么?

我一直很喜欢 Mono,并且得心应手,其它的项目大部分都是以某种方式围绕着它进行的。Gluezilla 是我在多年前开发的一个 Mozilla 绑定 binding ,可以把 C# 开发的应用嵌入到 Web 浏览器页面中,并且看起来很有特色。我开发过一个 Winform 应用,它是在 linux 上开发的,它可以在 Windows 上运行在一个 Mozilla 浏览器页面里嵌入的 GTK 视图中。CppSharp 项目(以前叫做 Cxxi,更早时叫做 CppInterop)是一个我开始为 C++ 库生成 C# 绑定 binding 的项目,这样就可以在 C# 中调用、创建实例、子类化 C++ 类。这样,它在运行的时候就能够检测到所使用的平台,以及用来创建本地运行库的是什么编译器,并为它生成正确的 C# 绑定 binding 。这多么有趣啊。

你怎样看跨平台开发的未来趋势呢?

我们构建本地应用程序的方式已经改变了,我感觉在各种桌面操作系统的明显差异在慢慢变得模糊;所以构建跨平台的应用程序将会更加容易,而且对系统的集成也不需要完全本地化。不好的是,这可能意味着应用程序易用性更糟,并且在发挥操作系统特性方面所能做的更少。库、工具以及运行环境的跨平台开发是一种我们知道怎样做的更好,但是跨平台应用程序的开发仍然需要我们的努力。


via: https://opensource.com/business/16/5/oscon-interview-andreia-gaita

作者:Marcus D. Hanwell 译者:vim-kakali 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出