BIND+GeoIP: 根据查询者IP的地理位置给出不同的DNS结果

为了能让访客访问到最快的服务器,可以在DNS上动手脚。有一些DNS服务商如dnspod可以根据DNS查询者的位置,给出相应的DNS解析结果。

自己搭建DNS服务器,也可以实现类似效果。在 BIND 9.10 中,提供了 GeoIP 的功能,利用 GeoIP 库查询访客IP所在区域,根据区域给出结果。参考:
https://kb.isc.org/article/AA-01149/0/Using-the-GeoIP-Features-in-BIND-9.10.html
继续阅读“BIND+GeoIP: 根据查询者IP的地理位置给出不同的DNS结果”

rpm是怎样安装/更新文件的?

这个问题的更准确表述是,在用rpm命令更新软件包时,这个软件包里的某个文件是逐渐改变的,还是原子的?

比如说,有一个软件包叫 fake-1.rpm,里面有A/B/C三个文件。这个软件包有一个更新版本 fake-2.rpm, 其中对B文件进行了变更。那么,在进行rpm的升级过程中,文件B会发生怎样的改变?在升级过程中,文件B有没有可能是不完整的?它的MD5值是yyy1234, yyy5678 还是其它值?

  fake-1.rpm (version 1)
  +-------+---------+
  | Files | MD5     |
  +-------+---------+
  | A     | xxx1234 |
  +-------+---------+
  | B     | yyy1234 |
  +-------+---------+
  | C     | zzz1234 |
  +-------+---------+

  fake-2.rpm (version 2)
  +-------+---------+
  | Files | MD5     |
  +-------+---------+
  | A     | xxx1234 |
  +-------+---------+
  | B     | yyy5678 |
  +-------+---------+
  | C     | zzz1234 |
  +-------+---------+

继续阅读“rpm是怎样安装/更新文件的?”

文件系统的 nodev 挂载选项有什么用?

nodev挂载选项有什么用?

一些安全策略会要求,除了根目录(/),其他目录如果挂载了单独的分区,应该添加 nodev 挂载选项。
所以 nodev 有什么用呢? mount 的 man 手册如此解释:

nodev  Do not interpret character or block special devices on the file system.

好吧,看完我还是没理解这个选项到底是干嘛的。网上搜索到了几个回答[2][3]。如果在挂载时,添加了nodev选项,那么系统不会把该文件系统里面的 block/character 文件当作是 block/character 文件来处理。

举个例子,一位别有用心的用户,在他有权限的机器上(比如他的笔记本),在U盘上创建了一个 block 文件,指向 sd* 之类的数据盘,这么巧他有权限把U盘插到服务器上,这么巧服务器自动挂载了这个U盘且没有 nodev 挂载选项,那么这位用户就能通过这个 block 文件读取到服务器上相应磁盘的数据。

继续阅读“文件系统的 nodev 挂载选项有什么用?”

在两节点Pacemaker集群中使用Quorum Device来避免fencing race

使用场景

两节点集群示例
- 在一个两节点高可用集群中,心跳和fence设备不在同一个网络;
- 如果心跳网络出现异常,两个节点则会出现分离;
- 在 Corosync 2.x 中,两节点默认(必须)开启two_node模式,在这个分离的情况下,两节点均可达到quorate的状态;
- 由于fence网络可以正常连同,两节点会互相fence对方,造成fencing race,两节点均被重启而无法提供服务;
两节点心跳丢失示意
继续阅读“在两节点Pacemaker集群中使用Quorum Device来避免fencing race”

用 mmap 将某些 struct 存放到文件中 (map virtual memory to a file)

背景

在 RHEL7 中, dovecot 在运行的过程中其中一个 imap 进程挂掉,出来这么一个 coredump.

Program terminated with signal 7, Bus error.

(gdb) f 0
#0  0x00007fbb15868c17 in mail_cache_transaction_open_if_needed (ctx=ctx@entry=0x7fbb173c1430)
    at mail-cache-transaction.c:218
218				if (ext->reset_id == cache->hdr->file_seq || i == 2)

(gdb) p cache
$1 = (struct mail_cache *) 0x7fbb173af2d0

(gdb) p cache->hdr
$3 = (const struct mail_cache_header *) 0x7fbb15ce5000

(gdb) p cache->hdr->file_seq
Cannot access memory at address 0x7fbb15ce5008

# cat maps | grep 7fbb15ce5000
7fbb15ce5000-7fbb15ced000 r--s 00000000 00:2c xxxxxxxxx    /xxxxxxx/dovecot.index.cache

挂掉的原因是 "signal 7, bus error" ((bad memory access)). 从 gdb 中可以看到,进程挂的时候在尝试访问 ext->reset_id 和 cache->hdr->file_seq, 而从 maps 可以看出 cache->hdr 指向的是 file-backend 的地址空间。

那么问题来了,怎样可以把一个结构体,映射到一个文件,而不是匿名页?另外一个问题是,在 gdb 中看到 “Cannot access memory at address” 是意味着这段地址存在问题吗?

测试环境

Debian 8 - jessie
继续阅读“用 mmap 将某些 struct 存放到文件中 (map virtual memory to a file)”