HP ProLiant MicroServer Gen8使用Super GRUB2 Disk从TF卡启动光驱位安装的Debian 8.3

简介


MicroServer Gen8属于HPE(Hewlett Packard Enterprise,惠普企业级产品)而不是HP,MicroServer Gen8的支持页面(如驱动下载)在HPE,官网首页是http://www.hpe.com,不是http://www.hp.com

HPE大约从2015年起变更了服务支持策略,普通驱动可以无限制下载,但是BIOS、SPP更新等可能需要用主机序列号注册、且在主机质保期内方能下载,超期就只能等待别人搬运分享了。

MicroServer Gen8在AHCI模式时,五个SATA和普通主板的功能一样,唯一不同的是MS G8的BIOS不能选择用哪个硬盘启动。
它会尝试从SATA1引导,如果SATA1没有连接硬盘,则尝试从SATA2引导,以此类推。
可是SATA1~4是硬盘笼子;通常人们都是将4个3.5寸仓库盘放到笼子里面;然后通过SATA5连接一个2.5寸硬盘(放置在9.5mm光驱位置)做系统盘。当五个硬盘都连接时,BIOS仅尝试从SATA1引导,结果出现引导失败。

解决方法就是通过安装一个U盘或MicroSD卡,从而间接引导SATA5接口上的系统盘。

网上给出的方法都是引导Windows系统的,而我们安装的如果是Linux系统的话,则无法简单的使用这些方法来引导系统的。
自己探索了一下,通过使用Rufus来使用并且修改Super GRUB2 Disk的方式来启动Debian的方法。

解决方法


1.安装Debian Linux系统

只插上光驱位置上的硬盘,然后安装Debian Linux系统,只有这样,才能正常安装系统,否则会出现无法安装到正确的磁盘上面。

2.开启SATA AHCI模式

通过 Intelligent Provisioning安装根本就找不到 tf卡(在 bios中可以把默认的 Dynamic HP Smart Array改成 SATA AHCI模式后就可以顺利安装了,但这样 raid功能也没了)

sata-mode-in-bios

3.下载必须的软件

下载Super GRUB2 Disk最新的镜像文件,官网为http://www.supergrubdisk.org/,一定要下载hybrid版本。
下载Rufus最新的版本,官网地址为https://rufus.akeo.ie/
也可以在本网站下载我使用的版本Super GRUB2 Diskrufus-3.10

4.安装Super GRUB2 Disk到SD卡

按照下图的步骤处理:

如果使用2.8.x版本,参考下图(注意,如果使用最新的2.0.4版本的Super GRUB2 Disk,只能使用3.11.x版本的Rufus

Rufus-ISO-Select
Rufus 2.8.886

只有如下选项才能保证可以在Windows中可以正常访问修改Super GRUB2 Disk已经安装到SD卡上的内容。

Rufus-ISO-Select-ISOHybrid

如果使用3.10.x版本(已知Rufus 3.11.1678写入的数据无法引导系统,只能使用3.10.x版本),参考下图

Rufus 3.10.1647

只有如下选项才能保证可以在Windows中可以正常访问修改Super GRUB2 Disk已经安装到SD卡上的内容。

5.增加Gen8的启动配置文件

在刻录好的SD卡的\boot\grub(Super GRUB2 Disk 2.02)或者\boot\grub\sgd(Super GRUB2 Disk 2.04)目录下创建一个名为Gen8.cfg的配置文件,内容如下:

一般建议是通过指定磁盘的uuid的方法来启动系统,如果能够确定系统磁盘上存在一个唯一的文件,也可以通过简单的指定文件的方法来让GRUB2来搜索的方式找到启动磁盘。

对于 Super GRUB2 Disk 2.02
修改\boot\grub\main.cfg,在
process_main_option "${prefix}/language_select.cfg"
这行代码下面增加
process_enable "${prefix}/Gen8.cfg" rootmenu

对于 Super GRUB2 Disk 2.04
修改\boot\grub\sgd\main.cfg,在
process_main_option "${sg2d_directory}/language_select.cfg"
这行代码下面增加
process_enable "${sg2d_directory}/Gen8.cfg" rootmenu

并且打开被注释掉的set timeout=10项目,让系统自动启动,否则需要手工点击一下回车。
修改后的内容如下:

6.插上SD卡,断电,然后冷重启

7.常见问题

注意:如果安装升级的是ubuntu 20.04.1,系统启动的时候,会出现error: symbol 'grub_calloc' not found

如下图:

但是奇怪的是,如果在系统启动的时候选择Detect and show boot methods,显示出的任何菜单,都可以正常启动系统,如下:

这个问题是因为ubuntu 20.04.1系统使用的是新版本的grub2引导系统,启动配置信息需要进行调整,修改我们创建的\boot\grub\Gen8.cfg(Super GRUB2 Disk 2.02)或者\boot\grub\sgd\Gen8.cfg(Super GRUB2 Disk 2.04),内容调整为如下:

参考链接


  1. 制作HP MicroServer Gen8可用的ESXi 5.x SD/TF卡启动盘
  2. HP ProLiant MicroServer Gen8迷你服务器 汇总贴:降噪、升级、改造
  3. Rescatux & Super Grub2 Disk
  4. Rufus
  5. HP ProLiant MicroServer Gen8 资源:SPP 2016.04、iLO4 2.40
  6. Gen8通过TF卡启动光驱位硬盘的新办法(增减硬盘无需改动)
  7. GRUB
  8. GNU GRUB Manual 2.04
  9. grub boot error : "symbol 'grub_calloc' not found

gitlab: MergeRequest、reset

Merge request

什么是Merge request,多人开发项目时,发起将一个远程分支merge到另一个分支(一般为主分支)的请求。

merge request步骤:

1.如果开发完了某个模块的功能,需要提交到线上。

2.首先,git fetch --all,仓库代码图拉下来,把线上的代码更新后合并到自己的本地分支上。

3.解决冲突

4.再次合并代码,没有问题后,git push origin 本地分支名。这样就会在远程仓库创建一个remotes/origin/本地分支名 的分支。

5.gitlab上,,进入mergeRequest页面,选择newMergeRequest(右上角绿色按钮)。merge

6.选择要merge的source分支,CONTINUE。

7.填写描述,添加reviwer(重要)。

8.等待结果,如果有冲突,需要从头再来。

Reset

bg2014061202

 

git reset 撤销命令

reset有三种模式

git reset --soft HEAD 本地文件不变,撤销掉commit,不撤销index

git reset --hard HEAD 本地文件改为HEAD,所有commit/index都修改掉

git reset HEAD     本地文件不变,撤销掉commit/index

 

如果只想恢复某一个文件,只需要

git checkout filename

恢复所有文件到当前HEAD

git checkout .

 

Ubuntu 14.04系统Apache 2.4.7版本使用mod_headers过滤HTTP响应头中的WP-Super-Cache字段

服务器上面安装了WP-Super-Cache后,服务器的响应报文中会自动增加一个WP-Super-Cache字段,这个字段会暴露服务器的一些细节,而WP-Super-Cache的设置中又没有找到去掉这个字段的设置选项。

如下图:

WP-Super-Cache-Http-Response

比较简单的解决方法就是,使用Apache2自带的mod_headers模块,通过修改.htacess配置文件的方式来去掉这个响应信息。

1.在网站目录下的.htacess文件中增加如下语句

2.启用mod_headers模块

3.重启Apache2服务

Ubuntu 14.04主机优化加速mod_pagespeed安装使用

背景介绍


谷歌优化加速mod_pagespeed作为Apache HTTP Server的module,它能在服务网页请求的即时做出超过15种的优化调整,包括优化缓存,最小化客户端—服务器往返路程,压缩有效传输体积。
经过实验观察,mod_pagespeed最高能使页面加载时间压缩50%。
项目已经被迁移到了GitHub,链接地址为:https://github.com/pagespeed/mod_pagespeed

Apache mod_pagespeed安装方法


1.下载安装包

32位系统

64位系统

鉴于国内被和谐的情况,可以本站下载 64位Ubuntu点击这里 32位Ubuntu点击这里

2.安装

3.重启Apache2

4.检查是否安装成功

5.潜在问题

安装这个插件之后,可能会导致页面在不同操作系统之间的显示错乱问题,目前WordPress上会出现这种问题,应该是缓存导致的问题,因为WordPress会根据系统,浏览器的不同来进行页面兼容处理,如果直接返回缓存数据,反而会出问题。目前暂时只能是禁用这个插件了。

另外,当主机的CPU,内存有限的情况下,这个模块反而增加了系统开销,导致系统响应缓慢。有些Javascript代码被优化后,会工作不正常,目前看来,对小网站来说副作用大于正面作用。

参考链接


主机优化加速mod_pagespeed和ngx_pagespeed安装使用

Ubuntu 14.04使用OpCache提升PHP5.5+程序性能

概述


PHP 5.5以后内建了OpCache,OpCache的加速原理是把编译后的bytecode存储在内存里面, 避免重复编译 PHP 所造成的资源浪费.Ubuntu 14.04默认自带 PHP 5.5.9,已经集成了这个功能。但是默认是不启用的。

启用


修改 php.ini 文件

在文件最后面加入:

重启服务器

效果


加速效果极端明显,强烈建议启用这个功能。

Ubuntu14.04升级到Ubuntu16.04出现错误

Ubuntu14.04升级到Ubuntu16.04出现错误,如下图所示:
from_ubuntu_14_upgrade_ubuntu_16_error
如果机器上安装了postgresql,则是由于postgresql处于升级黑名单中,因此无法升级。
一般建议手工卸载postgresql

卸载完成后继续执行升级命令

具体参考这个BUG的链接:
postgresql packages in the removal blacklist making it hard to upgrade

Ubuntu 14.04编译安装Apache 2.4.20

1.安装开发工具包

2.下载Apache 2.4.20的源代码

3.安装apr依赖库

4.安装pcre

5.解压缩代码

6.配置并编译

参考链接


Ubuntu 14.04系统WordPress 4.5升级到PHP7之后执行插件升级报错“无法定位WordPress内容目录(wp-content)”

Ubuntu 14.04系统上WordPress 4.5升级到PHP7之后执行插件升级报错,

如下图所示:WordPres_wp-content

这个是由于PHP升级之后,有些函数的支持出现了变化,导致调用失败。

目前已知的修复方法是修改wp-admin/includes/class-wp-filesystem-ssh2.php中的如下的几个函数:

修改为:

参考链接


Work around PHP7 php-ssh2 breakage

Ubuntu 14.04(64位)编译安装PHP7.0.5后编译安装libssh2-php

在使用Ubuntu 14.04(64位)源码编译安装PHP7并配置Apache2支持之后,无法直接通过命令安装libssh2-php,因此需要手工编译安装。

1.安装编译libssh2-php需要的依赖库

2.下载libssh2-php的源代码

3.解压缩文件

4.切换到目录

5.使用phpize配置插件编译环境

6.配置编译环境

7.编译并安装

执行之后,文件被安装到了/opt/php-7.0.5/lib/php/extensions/no-debug-zts-20151012目录下面。

8.配置php.ini加载插件

找到如下内容

在最下面增加

9.重启Apache2加载动态模块

gl接口耗时?

调用glclear接口,发现它耗时比较长,翻了翻stackoverflow。

Measuring the elapsed time of an OpenGL API call is mostly meaningless.

研究OpenGL接口的耗时是无意义的。

Asynchronicity

The key aspect to understand is that OpenGL is an API to pass work to a GPU.

The easiest mental model (which largely corresponds to reality) is that when you make OpenGL API calls, you queue up work that will later be submitted to the GPU. For example, if you make a glDraw*() call, picture the call building a work item that gets queued up, and at some point later will be submitted to the GPU for execution.

In other words, the API is highly asynchronous. The work you request by making API calls is not completed by the time the call returns. In most cases, it's not even submitted to the GPU for execution yet. It is only queued up, and will be submitted at some point later, mostly outside your control.

A consequence of this general approach is that the time you measure to make a glClear() call has pretty much nothing to do with how long it takes to clear the framebuffer.

Synchronization

Now that we established how the OpenGL API is asynchronous, the next concept to understand is that a certain level of synchronization is necessary.

Let's look at a workload where the overall throughput is limited by the GPU (either by GPU performance, or because the frame rate is capped by the display refresh). If we kept the whole system entirely asynchronous, and the CPU can produce GPU commands faster than the GPU can process them, we would be queuing up a gradually increasing amount of work. This is undesirable for a couple of reasons:

  • In the extreme case, the amount of queued up work would grow towards infinity, and we would run out of memory just from storing the queued up GPU commands.
  • In apps that need to respond to user input, like games, we would get increasing latency between user input and rendering.

To avoid this, drivers use throttling mechanisms to prevent the CPU from getting too far ahead. The details of how exactly this is handled can be fairly complex. But as a simple model, it might be something like blocking the CPU when it gets more than 1-2 frames ahead of what the GPU has finished rendering. Ideally, you always want some work queued up so that the GPU never goes idle for graphics limited apps, but you want to keep the amount of queued up work as small as possible to minimize memory usage and latency.

Meaning of Your Measurement

With all this background information explained, your measurements should be much less surprising. By far the most likely scenario is that your glClear() call triggers a synchronization, and the time you measure is the time it takes the GPU to catch up sufficiently, until it makes sense to submit more work.

Note that this does not mean that all the previously submitted work needs to complete. Let's look at a sequence that is somewhat hypothetical, but realistic enough to illustrate what can happen:

  • Let's say you make the glClear() call that forms the start of rendering frame n.
  • At this time, frame n - 3 is on the display, and the GPU is busy processing rendering commands for frame n - 2.
  • The driver decides that you really should not be getting more than 2 frames ahead. Therefore, it blocks in your glClear() call until the GPU finished the rendering commands for frame n - 2.
  • It might also decide that it needs to wait until frame n - 2 is shown on the display, which means waiting for the next beam sync.
  • Now that frame n - 2 is on the display, the buffer that previously contained frame n - 3 is not used anymore. It is now ready to be used for frame n, which means that the glClear()command for frame n can now be submitted.

Note that while your glClear() call did all kinds of waiting in this scenario, which you measure as part of the elapsed time spent in the API call, none of this time was used for actually clearing the framebuffer for your frame. You were probably just sitting on some kind of semaphore (or similar synchronization mechanism), waiting for the GPU to complete previously submitted work.

Conclusion

Considering that your measurement is not directly helpful after all, what can you learn from it? Unfortunately not a whole lot.

If you do observe that your frame rate does not meet your target, e.g. because you observe stuttering, or even better because you measure the framerate over a certain time period, the only thing you know for sure is that your rendering is too slow. Going into the details of performance analysis is a topic that is much too big for this format. Just to give you a rough overview of steps you could take:

  • Measure/profile your CPU usage to verify that you are really GPU limited.
  • Use GPU profiling tools that are often available from GPU vendors.
  • Simplify your rendering, or skip parts of it, and see how the performance changes. For example, does it get faster if you simplify the geometry? You might be limited by vertex processing. Does it get faster if you reduce the framebuffer size? Or if you simplify your fragment shaders? You're probably limited by fragment processing.

 

OpenGL是GPU的API

API call是以eventloop的形式工作

但需要一定的同步工作,任务数量太多,延迟会变大,开发者又需要尽快响应用户,GPU需要跟CPU保持一定过得同步。简单的来说,如果CPU发出的绘制指令超出GPU太多(1-2帧),GPU会锁住CPU。

在这个背景下,就可以解释为什么glClear耗时了,因为它触发了一次同步。

已3个缓冲区为例,n-3在绘制,n-2在合成,The driver decides that you really should not be getting more than 2 frames ahead。glClear就会block住,直到GPU工作完。

GPU工作渲染完n-2,glClear就会提交n。

最终结论,绘制太慢导致的。

可以看看CPU消耗,看看是不是CPU被锁住了。