星期二, 七月 31, 2007

python assemble methods at runtime?

在以前曾经讨论过一个例子:python unzip,当时在外部定义了一个函数,然后直接利用 setattr 将其加入到 ZipFile 类对象中,如下:
>>> class test:
... pass
...
>>> def func(self):
... print self.__dict__
...
>>> test.func = func
>>> t = test()
>>> t.func()
{}
>>>
但是,如果在类定义中直接使用,则不行:
>>> def func(self):
... print self.__dict__
...
>>> class test:
... def __init__(self):
... self.func = func
...
>>> t = test()
>>> t.func()
Traceback (most recent call last):
File "", line 1, in
TypeError: func() takes exactly 1 argument (0 given)
使用 setattr 也不行:
>>> def func(self):
... print self.__dict__
...
>>> class test:
... def __init__(self):
... setattr(self, 'func', func)
...
>>> t = test()
>>> t.func()
Traceback (most recent call last):
File "", line 1, in
TypeError: func() takes exactly 1 argument (0 given)
但是,是不是我放在外面定义就没有一点问题了呢?在 mirrord.py 中,我就希望在运行时再装配,因为直接在 __init__ 中定义不行,所以我这样做:
def _schedule_thread(self, Server, address):
that = threading.Thread(
target=self.__run_schedule, name='schedule', args=(Server, address))
that.setDaemon(1)
that.start()
that.join()

def _schedule_process(self, Server, address):
"""
There is a sharing problem has not been solved:
manager(WatchManager) should be shared among processes
"""
pid = os.fork()
if pid == 0: self.__run_schedule(Server, address)

class Mirrord:
...
def __run_schedule(self, Server, address):
...
Mirrord._schedule = _schedule_thread
结果在测试的时候报错:
Exception in thread mirrord:
Traceback (most recent call last):
File "/usr/lib/python2.5/threading.py", line 460, in __bootstrap
self.run()
File "/usr/lib/python2.5/threading.py", line 440, in run
self.__target(*self.__args, **self.__kwargs)
File "mirrord_ut.py", line 56, in __run_thread
self.mrd.run(('localhost', 2123))
File "/root/ulfs/cutils/trunk/lib/mirrord.py", line 497, in run
self._schedule(Server, address)
File "/root/ulfs/cutils/trunk/lib/mirrord.py", line 380, in _schedule_thread
target=self.__run_schedule, name='schedule', args=(Server, address))
AttributeError: Mirrord instance has no attribute '__run_schedule'
,而如果将那两个函数改为:
def _schedule_thread(self, Server, address):
that = threading.Thread(
target=self._Mirrord__run_schedule, name='schedule', args=(Server, address))
that.setDaemon(1)
that.start()
that.join()

def _schedule_process(self, Server, address):
"""
There is a sharing problem has not been solved:
manager(WatchManager) should be shared among processes
"""
pid = os.fork()
if pid == 0: self._Mirrord__run_schedule(Server, address)
则可以通过。但显然使用 _Mirrord__run_schedule 这种方式看上去不是太好!

python forking after threading?

现在需要对 mirrord 进行单元测试,但 mirrord 进行了 daemon switch,因此会 fork 子进程并退出父进程。而在单元测试中,我的测试程序只能通过创建子进程或子线程来运行工作代码(否则运行到 daemon 状态就阻塞进入无限循环,测试代码就没办法往下走了),为了得到工作代码的状态来进行检测,需要能够访问到工作代码的一些变量,所以简单的就是使用线程。

但问题是,如果在 threading 之后又进行了 forking,而 fork 后的父进程退出,那么线程是否退出呢?写一个原型代码看看:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import os,sys
import time
import threading

def run_thread():
pid = os.fork()
if pid == 0:
print "child process ..."
while True:
time.sleep(5)
print "child process is running ..."
print "main process exiting ..."
sys.exit(0)

that = threading.Thread(target=run_thread, name="child")
that.setDaemon(1)
that.start()
# #1:
that.join()
print "main thread end"
运行结果如下:
sh$ python mirrord_5_ut.py
child process ...
main process exiting ...
main thread end
[Ctrl^C]
sh$ child process is running ...
child process is running ...
child process is running ...
[Ctrl^C]
sh$ child process is running ...
由此可见,fork 后的子进程还在运行,但是主进程退出了,也导致调度它的线程退出了!

但有一个问题,如果在 thread code 中 fork 的子进程也退出,那么在上面 #1 后面的代码会不会执行?因为进程是复制地址空间的,例如:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

"""
If the main process exits after forking,
while the forking is execute by a child thread,
will the main/child threads end? -- Yes
Author: Roc Zhou
Date: 2007-07-31
Email: chowroc.z@gmail.com
"""

import os,sys
import time
import threading

var = 0

def run_thread():
global var
var = 1
print "var is '%d' in thread" % var
pid = os.fork()
if pid == 0:
print "child process ..."
i = 0
while i < 10:
var = i * 2
time.sleep(1)
print "child process is running %d and var is '%d' ..." % (i, var)
i += 1
else:
print "main process ..."
j = 0
while j < 10:
var = j * 2 + 1
time.sleep(1)
print "main process is running %d and var is '%d' ..." % (j, var)
j += 1
# sys.exit(0)
print "var is '%d' at the end of thread code" % var

print "var is '%d' at the beginning" % var
# #a:
# run_thread()
# ------------
# #b:
that = threading.Thread(target=run_thread, name="child")
that.setDaemon(1)
that.start()
time.sleep(5)
# #1:
that.join()
# ------------
print "var is '%d' at the main thread end" % var
当按照 #a 来运行的时候,没有启动线程,那么输出结果是:
sh$ python mirrord_5_ut.py
var is '0' at the beginning
var is '1' in thread
child process ...
main process ...
main process is running 0 and var is '1' ...
child process is running 0 and var is '0' ...
main process is running 1 and var is '3' ...
child process is running 1 and var is '2' ...
main process is running 2 and var is '5' ...
child process is running 2 and var is '4' ...
main process is running 3 and var is '7' ...
child process is running 3 and var is '6' ...
main process is running 4 and var is '9' ...
child process is running 4 and var is '8' ...
main process is running 5 and var is '11' ...
child process is running 5 and var is '10' ...
main process is running 6 and var is '13' ...
child process is running 6 and var is '12' ...
main process is running 7 and var is '15' ...
child process is running 7 and var is '14' ...
main process is running 8 and var is '17' ...
child process is running 8 and var is '16' ...
main process is running 9 and var is '19' ...
var is '19' at the end of thread code
var is '19' at the main thread end
sh$ child process is running 9 and var is '18' ...
var is '18' at the end of thread code
var is '18' at the main thread end
可以看到,最后的代码运行了两次!但是在调用线程之后就不是,按 #b 运行,输出结果如下:
sh$ python mirrord_5_ut.py
var is '0' at the beginning
var is '1' in thread
child process ...
main process ...
child process is running 0 and var is '0' ...
main process is running 0 and var is '1' ...
child process is running 1 and var is '2' ...
main process is running 1 and var is '3' ...
child process is running 2 and var is '4' ...
main process is running 2 and var is '5' ...
child process is running 3 and var is '6' ...
main process is running 3 and var is '7' ...
child process is running 4 and var is '8' ...
main process is running 4 and var is '9' ...
child process is running 5 and var is '10' ...
main process is running 5 and var is '11' ...
child process is running 6 and var is '12' ...
main process is running 6 and var is '13' ...
child process is running 7 and var is '14' ...
main process is running 7 and var is '15' ...
child process is running 8 and var is '16' ...
main process is running 8 and var is '17' ...
child process is running 9 and var is '18' ...
var is '18' at the end of thread code
main process is running 9 and var is '19' ...
var is '19' at the end of thread code
var is '19' at the main thread end
这里最后的代码只运行了一次!

另外,是否使用 #1 处的 that.join() 也是有差别的!
sh$ python mirrord_5_ut.py
var is '0' at the beginning
var is '1' in thread
child process ...
main process ...
child process is running 0 and var is '0' ...
main process is running 0 and var is '1' ...
child process is running 1 and var is '2' ...
main process is running 1 and var is '3' ...
child process is running 2 and var is '4' ...
main process is running 2 and var is '5' ...
child process is running 3 and var is '6' ...
main process is running 3 and var is '7' ...
var is '9' at the main thread end
sh$ child process is running 4 and var is '8' ...
child process is running 5 and var is '10' ...
child process is running 6 and var is '12' ...
child process is running 7 and var is '14' ...
child process is running 8 and var is '16' ...
child process is running 9 and var is '18' ...
var is '18' at the end of thread code
所以,最终,将 mirrord.py 这个 module 中的 daemon 的代码移到 mirrord 这个 script 中!

星期一, 七月 30, 2007

python list pop operation 的一个典型

下面可能可以算得上是一个 List pop 操作的典型情况,是在一段单元测试代码中,我需要对某个目录下的文件进行查找,找到所有比指定时间要新的普通文件:
basedir = "/usr/local"
txlist = ["t:%s/etc" % basedir, "t:%s/share" % basedir, "x:%s/share/man"]

expect = []
for fname in self.__find_rfiles("%s/etc" % basedir): expect.append(fname)
for fname in self.__find_rfiles("%s/share" % basedir): expect.append(fname)
for fname in self.__find_rfiles("%s/share/man" % basedir): exclude.append(fname)
for fname in exclude: expect.remove(fname)
j = random.randint(0, len(expect))
ftemp = expect[j]
temp = os.lstat(ftemp)[-1]
ttemp = datetime.datetime(*time.localtime(temp)[:6])
rmidx = []
# #1:
for fname in expect:
temp = os.lstat(fname)[-1]
fctime = datetime.datetime(*time.localtime(temp)[:6])
if fctime > ttemp: rmidx.append(fname)
# #2:
for fname in rmidx:
expect.remove(fname)

fsbk = fs_backup.FsBackup(identity='test')
fsbk.append(txlist)
_files = fsbk.find(lasttime=ttemp)
_files.sort()
expect.sort()
self.failUnlessEqual(_files, expect)
self.__clean_last(fsbk)
这里,首先无法在位置 #1 处直接对 expect 进行 remove() 或 pop() 操作,因为这个操作会对当前列表的索引产生影响,导致当前位置指针指向了错误的项,所以会漏掉下一个节点,这在:python list pop in loop 中已经说明。

一种办法是使用在 python list pop in loop, 补充 中说明的方法,对指针进行调整。而这里采用另一种方法,建立一个不同的索引,每次都对重新寻找 expect 中指定节点的位置,这样指针位置就不会错了。

如果列表很大,那么每次搜寻索引可能会导致开销很大,那么可以考虑使用 dict(hash table) 来替换列表!

星期日, 七月 29, 2007

python list pop in loop, 补充

>>> L = ['La', 'Lb', 'c', 'Ld']
>>> x = 0
>>> for i in range(len(L)):
... print i
... if x: i -= 1
... if L[i][0] == 'L': L.pop(i); x = 1
... else: x = 0
...
0
'La'
1
'Lb'
2
'Ld'
3
Traceback (most recent call last):
File "", line 4, in ?
IndexError: list index out of range
这里如果要应用在多线程情况下,我考虑应该是将 x 扩展为一个队列,并应用生产者/消费者模式

python variables sharing between threads

python list pop in loop 中说明了在循环中使用 pop 的问题,同时说明的多进程的情况。因为在 mirrod/fs_mirror 项目中必须使用共享 WatchManager,所以可以考虑先看看线程的情况。
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import sys
import threading
import time
import random

L = [ chr(i+97) for i in range(26) ]
print L

idx = 20

def run_thread():
# print "index: %d, %s" % (idx, L[idx])
for x in L:
i = L.index(x)
# print "thread: %d, %s" % (i, x)
time.sleep(1)
if i == idx:
for j in range(int(random.random() * 10000)): sys.stdout.write("*")
print
print "thread: %d, %s" % (i, x)
try:
i = L.index(x)
except ValueError:
print "index: %d, %s" % (i, L[i])
# Has been pop out
if i == idx + 1:
print "index + 1: %d, %s" % (i, L[i])
print "Child thread end"
# print "Child List:", L

srv = threading.Thread(target=run_thread, name='child')
srv.setDaemon(1)
srv.start()
# L.extend(['x', 'y', 'z'])
# time.sleep(3)
for x in L:
i = L.index(x)
# print "main: %d, %s" % (i, x)
time.sleep(1)
if i == idx:
for j in range(int(random.random() * 10000)): sys.stdout.write("-")
print
print "main: %d, %s" % (i, x)
print "pop %d, %s" % (i, L[i])
L.pop(i)
print "Main thread end"
# print "Main List:", L
srv.join()
父线程会从列表中取出 L[20],子线程在 L[20] 出打印结果,看输出结果:
sh$ python mirrord_4_sharing_thread.py
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
------...
main: 20, u
pop 20, u
******...
thread: 20, u
index: 20, v
index + 1: 21, w
Main thread end
Child thread end
可以看到,在 main thread 取出 20, 'u' 的同时,child thread 开始认为 20 是 'u',但马上由变成了 20, 'v',因为 20 在 for 中已经走过以此,因此在下一个循环中将直接进入 21,这是 'v' 就被 child thread 忽略了!

这里,必须考虑 Lock 的问题!

python list pop in loop

如果在一个列表中循环时做了 pop 操作,会有什么问题呢:
>>> L = ['a', 'b', 'c', 'd']
>>> for i in range(len(L)):
... x = L[i]
... if x == 'b': L.pop(i)
...
'b'
Traceback (most recent call last):
File "", line 2, in ?
IndexError: list index out of range
这里已经报错了。但如果换一种方法呢?
>>> L = ['a', 'b', 'c', 'd']
>>> for x in L:
... if x == 'b':
... i = L.index(x)
... L.pop(i)
...
'b'
>>> print L
['a', 'c', 'd']
这里看上去是对的,但会有潜在的问题?例如这样的情况:

>>> L = ['La', 'Lb', 'c', 'Ld']
>>> for x in L:
... if x[0] == 'L':
... i = L.index(x)
... L.pop(i)
...
'La'
'Ld'
>>> print L
['Lb', 'c']

>>> L = ['La', 'Lb', 'c', 'Ld']
>>> for x in L:
... if x[0] == 'L':
... L.remove(x)
...
>>> print L
['Lb', 'c']
那么如果是在多进程环境中呢?

看这个:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import os,time

L = [ chr(i+97) for i in range(7) ]
print L
pid = os.fork()
if pid == 0:
for x in L:
print x
time.sleep(3)
print "Child process end"
print "Child List:", L
else:
L.extend(['x', 'y', 'z'])
j = 5
L.pop(j)
print "Main process end"
print "Main List:", L
其运行结果如下:
roc@crablfs:~/ulfs/cutils/trunk/prototypes$ python Ltest.py
['a', 'b', 'c', 'd', 'e', 'f', 'g']
a
Main process end
Main List: ['a', 'b', 'c', 'd', 'e', 'g', 'x', 'y', 'z']
roc@crablfs:~/ulfs/cutils/trunk/prototypes$ b
c
d
e
f
g
Child process end
Child List: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
可以看到子进程没有受到影响,因为进程的地址空间是复制的,如果是线程 thread,就不存在这个问题。

于是,对于 mirrod/fs_mirrod 项目来说,因为 inotify 的 WatchManager 必须共享(父进程/线程写入,子进程/线程读取并根据这个变动的 manager 来建立 Processor),所以如果使用进程解决方案,就必须考虑共享问题;同时共享问题包括一个对资源的锁定问题,即父进程对共享内容的变更可能导致服务子进程/线程读取到的信息不准确!

星期五, 七月 27, 2007

python list comprehension and function

以下两种方式都是可以的!:
real_fnames.extend([os.path.normpath(f) for f in files])
real_fnames.extend(os.path.normpath(f) for f in files)

星期四, 七月 26, 2007

ulfs 项目及其文档

现在把项目的所有相关内容都放到了 sourceforge 上,SVN 在:
https://crablfs.svn.sourceforge.net/svnroot/crablfs

项目改名为 ulfs,意为:
1. Your LFS
2. Templated LFS that make use of User Based Package Management

包括三个子项目和一个文档目录:
caxes 是关于配置管理的库和工具,包括基本数据结构的定义,例如现在利用 Python 的操作符重载定义的新的数据结构 Tree,目前完成了基本定义,下一步计划要进一步完善 Tree,之后再针对树和表及序列配置编写更多的接口库,以及为主机间配置共享编写 ctemplates 工具。

cutils 是建立在 caxes 上的工具集,主要利用 caxes 来实现语法及主机配置共享。包括备份和利用 inotify 机制实现的热备份工具,不依赖于具体协议的文件传输,以及利用 libgmail 实现对 gmail 的备份等...

目前在做的是 fs_backup 和 fs_mirror/mirrord,即备份和热备份工具,可以实现廉价和低耗的热备份机制,例如用 7 台主机为一组,5 台作为生产系统,1 台作为替换系统,1 台作为热备份系统,这样当生产系统中有一台有当机时,可以迅速切换到:
Replacer
||
[Net FS] <------> Hot-Backup-System
的模式。因为拷贝一次的代价是很大的,耗时也很长,如果数据量很大,则完全不能接受。而这种模式,比之于完全的双机热备要廉价得多。

当然这并不意味着可以放弃冷备份,因为热备份主要是用来抵御硬件故障,而对于误操作、病毒、入侵和软件故障则无能为力,当某个或部分用户需要恢复到之前某一段时间的状态时,只有利用冷备份才能实现。在这里,mirrord/fs_mirror 即热备系统的服务器代理(运行在生产系统上)和客户端(运行在 Hot-Backup-System),而 fs_backup 即为冷备份系统,他也可以被 mirrord 用来做启动同步,也可以被 fs_mirror 用来做与 mirrord 的初始化同步;同时可以在 Hot-Backup-System 上面运行 mirrord,在另外起一台冷备份运行 fs_mirror 来调用 fs_backup 做同步式的冷备份,这样可以形成一个链,同时也使开销更平均,避免出现过大的峰值。

ulfs 就是原来的 crablfs,即 User Based Package Managerment System。在 caxes 配置共享和管理的基础上,可以更进一步建立模板机制。

项目文档在:
http://crablfs.sourceforge.net/

关于 Tree 数据结构的代码内文档:
http://crablfs.sourceforge.net/tree.html

另外,关于系统管理和网络设施架构的笔记和经验总结:
http://crablfs.sourceforge.net/sysadm_zh_CN.html

python main process when raise in child thread?

如果是使用 forking,子进程异常退出应该不会影响到父进程的运行。而对于线程来说,地址空间是和主线程共享的,那么在子线程中产生的异常会不会影响到主线程的运行呢。编写一段代码测试之:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import threading

class Exc:
def __init__(self, msg): self.msg = msg

def run_thread():
raise Exc("rasie Exception in child thread")

st = threading.Thread(target=run_thread, name="child")
st.setDaemon(1)
st.start()
st.join()
print "Main Process End"

sh$ python threading_test.py
Exception in thread child:
Traceback (most recent call last):
File "/usr/lib/python2.5/threading.py", line 460, in __bootstrap
self.run()
File "/usr/lib/python2.5/threading.py", line 440, in run
self.__target(*self.__args, **self.__kwargs)
File "threading_test.py", line 10, in run_thread
raise Exc("rasie Exception in child thread")
Exc: <__main__.exc>

Main Process End
最后 Main Thread 仍然打印了 "Main Process End",说明主线程没有受到影响。

星期三, 七月 04, 2007

能够信赖你的电脑吗?

能够信赖你的电脑吗? 理查德·斯多尔曼 著
Posted by shentao at 2004-12-01 04:50 AM
http://gentoo.hsefz.com/linux/Linux%20Forum/public/794732524923/

没有警觉性的的眼睛太容易被蒙蔽了。

原文
http://www.gnu.org/philosophy/can-you-trust.cn.html

【本文是重要的 GNU 哲学页面, 请不吝於提供对於本文翻译的意见。 <chliu@gnu.org> 同时为了便於读者引用查找, 於中译文本上的每一段都附有参考标号。 我们也欢迎关於本文的各种讨论: <chinese-translators@gnu.org> 。】

Who should your computer take its orders from? Most people think their computers should obey them, not obey someone else. With a plan they call "trusted computing", large media corporations (including the movie companies and record companies), together with computer companies such as Microsoft and Intel, are planning to make your computer obey them instead of you. (Microsoft's version of this scheme is called "Palladium".) Proprietary programs have included malicious features before, but this plan would make it universal.

1 您的电脑应该听取谁的命令? 大部份的人认为他们的电脑应该服从他们而不是某个其他人。 经由一项他们称之为“可信赖的计算”(trusted computing)的打算, 大型的媒体公司(包括电影和录制公司) 以及像是 Microsoft 和 Intel 的电脑公司, 正打算要使您的电脑服从他们而不是您。 (这项方案的 Microsoft 版本称之为“安全装备”: Palladium 。) 私权的程序在以前就已经有包括了一些恶意的功能特色(features), 但是这项打算将会使其普遍化。

Proprietary software means, fundamentally, that you don't control what it does; you can't study the source code, or change it. It's not surprising that clever businessmen find ways to use their control to put you at a disadvantage. Microsoft has done this several times: one version of Windows was designed to report to Microsoft all the software on your hard disk; a recent "security" upgrade in Windows Media Player required users to agree to new restrictions. But Microsoft is not alone: the KaZaa music-sharing software is designed so that KaZaa's business partner can rent out the use of your computer to their clients. These malicious features are often secret, but even once you know about them it is hard to remove them, since you don't have the source code.

2 私权软件在本质上即表示: 您无法控制它要做些什么; 您不能研究源码或是更动它。 聪明的商人找出一些方法利用他们的控制, 来使您处於劣势的行为并不让人感到惊讶。 Microsoft 已经做过许多次了: 有一个版本的 Windows 被设计来将在您的硬碟上的所有软件回报给 Microsoft ; 一个最近在 Windows Media Player 上的“安全” 升级要求使用者同意新的限制(restrictions)。 但 Microsoft 并不孤单: KaZaa 这个音乐分享(music-sharing)软件被设计成, 使 KaZaa 的商业伙伴可以将您的电脑的使用出租给他们的客户。 这些恶意的功能特色通常是隐密的, 但是就算您发现到, 也很难将它们移除, 因为您并没有源码。

In the past, these were isolated incidents. "Trusted computing" would make it pervasive. "Treacherous computing" is a more appropriate name, because the plan is designed to make sure your computer will systematically disobey you. In fact, it is designed to stop your computer from functioning as a general-purpose computer. Every operation may require explicit permission.

3 在过去, 这些都是个别〔发生〕的事件。 “可信赖的计算”(Trusted computing)将可能使它变得普遍。 “背判了的计算”是一个较为合适的名称, 因为这项打算是设计用来确保您的电脑将会有系统地不服从您。 事实上, 它是设计用来使您的电脑无法作为一台通用的计算机(general-purpose computer)。 每一项操作都将会需要明确的许可〔才得以进行〕。

The technical idea underlying treacherous computing is that the computer includes a digital encryption and signature device, and the keys are kept secret from you. Proprietary programs will use this device to control which other programs you can run, which documents or data you can access, and what programs you can pass them to. These programs will continually download new authorization rules through the Internet, and impose those rules automatically on your work. If you don't allow your computer to obtain the new rules periodically from the Internet, some capabilities will automatically cease to function.

4 在「背判了的计算」底下的技术想法是: 电脑包括了一个数位加密(digital encryption) 以及签章(signature)装置, 而其键值(keys)对您来说则是〔无法取得的〕秘密。 私权程序将会使用这项装置来控制「您可以执行的其它程序」、 「您可以储存的文档或资料」以及「您可以传递的程序」。 这些程序将会持续地经由互联网下载新的认证规则(authorization rules), 并且自动地将那些规则加诸到您的工作上。 如果您不允许您的电脑定期地从互联网取得新的规则, 〔那么〕一些功能(capabilities)将会自动地停止作用(function)。

Of course, Hollywood and the record companies plan to use treacherous computing for "DRM" (Digital Restrictions Management), so that downloaded videos and music can be played only on one specified computer. Sharing will be entirely impossible, at least using the authorized files that you would get from those companies. You, the public, ought to have both the freedom and the ability to share these things. (I expect that someone will find a way to produce unencrypted versions, and to upload and share them, so DRM will not entirely succeed, but that is no excuse for the system.)

5 当然, 好莱坞(Hollywood)以及录制公司打算要将「背判了的计算」用到“DRM” (数位限制管理: Digital Restrictions Management)上, 这样一来下载的录像品(videos)和音乐就只能够在一台指定的电脑上播放。 分享将是完全的不可能, 至少使用您可能从那些公司下载的认证档案是如此。 您,也就是公众, 应当同时拥有自由和能力来分享这些事物。 (我期望将有某个人能找出一个制作出没有加密版本的方法, 并且上载分享它们, 这样子 DRM 将不会完全地成功, 但那不能作为这个体系〔合理化〕的藉口。)

Making sharing impossible is bad enough, but it gets worse. There are plans to use the same facility for email and documents--resulting in email that disappears in two weeks, or documents that can only be read on the computers in one company.

6 使得分享变得不可能已经是够糟的了, 但还有更糟的。 他们打算要使用同样的设施(facility)到电子邮件和文档上 -- 造成电子邮件会在两个星期内消失, 或是文档只可以在一间公司内的电脑上被阅读。

Imagine if you get an email from your boss telling you to do something that you think is risky; a month later, when it backfires, you can't use the email to show that the decision was not yours. "Getting it in writing" doesn't protect you when the order is written in disappearing ink.

7 设想如果您从您的老板那里收到一封电子邮件, 要求您去做一件您认为太过於冒险的事; 一个月后, 这事情与〔他的〕预期相反时, 您无法使用那封电子邮件来显示那个决定并不是您所作出的。 当这个命令是以会消失的墨水撰写时, “白纸黑字地写下来”并不足以保护您。

Imagine if you get an email from your boss stating a policy that is illegal or morally outrageous, such as to shred your company's audit documents, or to allow a dangerous threat to your country to move forward unchecked. Today you can send this to a reporter and expose the activity. With treacherous computing, the reporter won't be able to read the document; her computer will refuse to obey her. Treacherous computing becomes a paradise for corruption.

8 设想如果您自您的老板那里收到一封电子邮件, 陈述了一个违反了法律或道德的政策, 像是将您的公司的帐簿丢进碎纸机, 或是允许一个对您的国家的严重威胁继续进行而不受检查。 在今天您可以将这类事情送给〔新闻〕记者并揭露这个活动。 但是经由「背判了的计算」, 记者将无法阅读这份文档, 她的电脑将会拒绝服从她。 「背判了的计算」变成了舞弊的天堂。

Word processors such as Microsoft Word could use treacherous computing when they save your documents, to make sure no competing word processors can read them. Today we must figure out the secrets of Word format by laborious experiments in order to make free word processors read Word documents. If Word encrypts documents using treacherous computing when saving them, the free software community won't have a chance of developing software to read them--and if we could, such programs might even be forbidden by the Digital Millennium Copyright Act.

9 像是 Microsoft Word 的文书处理器, 可以在当它们储存您的文档时使用「背判了的计算」, 以确保没有与之竞争的文书处理器可以阅读它们。 今天我们必须费力地尝试来理解 Word 格式〔为何〕, 以制作出可以阅读 Word 文档的自由文书处理器。 如果 Word 在当它储存文档时使用「背判了的计算」, 自由软件社团将不会有机会开发出可以阅读它们的软件 -- 即便我们办得到, 这样子的程序甚至也会被“数位千禧年版权法案” (Digital Millennium Copyright Act)所禁止。

Programs that use treacherous computing will continually download new authorization rules through the Internet, and impose those rules automatically on your work. If Microsoft, or the US government, does not like what you said in a document you wrote, they could post new instructions telling all computers to refuse to let anyone read that document. Each computer would obey when it downloads the new instructions. Your writing would be subject to 1984-style retroactive erasure. You might be unable to read it yourself.

10 使用「背判了的计算」的程序, 将会持续地自互联网下载新的认证规则, 并且将这些自动地加诸到您的工作上。 如果 Microsoft 或是美国政府不喜欢在某份您所撰写的文档中所说的事, 他们可以发出新的指示, 告诉所有的电脑拒绝让任何人阅读那份文档。 每一台电脑在它下载了新的指示后都将会遵守。 您的著述将会受到有如小说《一九八四》中所描述的(1984-style) 「追溯既往而有效的删去」(retroactive erasure)。 【《一九八四》(1984)是英国作家乔治·欧威尔(George Orwell) 於一九四九年发表的科幻小说; 相对应的则是赫胥黎(Aldous Huxley) 於一九三二年所发表的《美丽新世界》(Brave New World) -- 它也是《勇敢 GNU 世界》(Brave GNU World)名称的由来。】 您有可能连您自己都无法阅读它。

You might think you can find out what nasty things a treacherous computing application does, study how painful they are, and decide whether to accept them. It would be short-sighted and foolish to accept, but the point is that the deal you think you are making won't stand still. Once you come depend on using the program, you are hooked and they know it; then they can change the deal. Some applications will automatically download upgrades that will do something different--and they won't give you a choice about whether to upgrade.

11 您也许会想: 您可以看穿「“背判了的计算”的程序在做的卑鄙事」, 研究〔使用它们〕将会付出什么代价, 然后再来决定是否要使用它们。 接受将会是短视而且愚蠢的, 重点在於您认为您所作出的协议并不会保持不变。 一旦您变得依赖於使用〔那些〕程序, 您就被套牢了(hooked), 而且他们清楚得很; 然后他们就可以更动这项协议。 一些应用程序将会自动地下载「将会做出某些不一样的事情的」升级 -- 而他们可不会给您一个是否要升级的选择。

Today you can avoid being restricted by proprietary software by not using it. If you run GNU/Linux or another free operating system, and if you avoid installing proprietary applications on it, then you are in charge of what your computer does. If a free program has a malicious feature, other developers in the community will take it out, and you can use the corrected version. You can also run free application programs and tools on non-free operating systems; this falls short of fully giving you freedom, but many users do it.

12 今天您可以经由不去使用它来避免被私权软件所限制。 如果您执行 GNU/Linux 或是其它的自由操作系统, 并且如果您避免在它上面安装私权应用程序, 那么您就换得了〔完全地掌握〕您的电脑做些什么〔的自由〕。 如果一个自由程序有一个恶意的功能特色, 在社团里的其他程序员将会把它除去, 然后您就可以使用修正过的版本了。 您也可以在不自由的操作系统上执行自由的应用程序和工具; 这并不足以给予您完全的自由, 但是有许多使用者这么做。

Treacherous computing puts the existence of free operating systems and free applications at risk, because you may not be able to run them at all. Some versions of treacherous computing would require the operating system to be specifically authorized by a particular company. Free operating systems could not be installed. Some versions of treacherous computing would require every program to be specifically authorized by the operating system developer. You could not run free applications on such a system. If you did figure out how, and told someone, that could be a crime.

13 「背判了的计算」 将自由操作系统和自由应用程序的存续置於危险的境地, 因为您将根本无法执行它们。 一些版本的「背判了的计算」, 将会需要操作系统被某个特定的公司明确地给予认证。 自由的操作系统将无法被安装。 一些版本的「背判了的计算」, 将会需要每一个程序都要被操作系统开发者明确地给予认证。 您无法在这样的一个操作系统上执行自由的应用程序。 如果您真的了解了要如何做, 并且告诉了某人, 那可能是一种犯罪行为。

There are proposals already for US laws that would require all computers to support treacherous computing, and to prohibit connecting old computers to the Internet. The CBDTPA (we call it the Consume But Don't Try Programming Act) is one of them. But even if they don't legally force you to switch to treacherous computing, the pressure to accept it may be enormous. Today people often use Word format for communication, although this causes several sorts of problems (see "We Can Put an End to Word Attachments"). If only a treacherous computing machine can read the latest Word documents, many people will switch to it, if they view the situation only in terms of individual action (take it or leave it). To oppose treacherous computing, we must join together and confront the situation as a collective choice.

14 已经有一些在美国法律上的提议: 要求所有的电脑都支持「背判了的计算」, 并且禁止将旧电脑连结到互联网上。 CBDTPA (我们称它为“消费就好,不要试著编写程序”法案: Consume But Don't Try Programming Act)就是其中之一。 但是即使他们并没有在法律上强制您切换到「背判了的计算」, 〔被迫〕接受它的压力还是很大。 今天人们通常使用 Word 格式来通信, 虽然这会造成许多类型的问题。 (请见 “我们可以终结使用 Word 附加档案”:We Can Put an End to Word Attachments) 〔但是〕如果只有「背判了的计算」的机器可以阅读最新的 Word 文档, 并且如果他们所看到的形势只是以个别的动作(接受或离开)来表现时, 许多人将会切换到它。 为了反制「背判了的计算」, 我们必须结合在一起面对这个形势, 以作为我们集体的选择。

For further information about treacherous computing, see .

15 关於「背判了的计算」的更多信息, 请见

To block treacherous computing will require large numbers of citizens to organize. We need your help! The Electronic Frontier Foundation and Public Knowledge are campaigning against treacherous computing, and so is the FSF-sponsored Digital Speech Project. Please visit these Web sites so you can sign up to support their work.

16 要阻挡「背判了的计算」将会需要很大数目的公民组织起来。 我们需要您的帮助! 电子先锋基金会(Electronic Frontier Foundation)公众知识(Public Knowledge) 正在发起对抗「背判了的计算」的活动, 由自由软件基金会资助的 数位言论工程(Digital Speech Project) 也有参与。 请拜访这些网站, 这样您就可以签名来支持他们的工作了。

You can also help by writing to the public affairs offices of Intel, IBM, HP/Compaq, or anyone you have bought a computer from, explaining that you don't want to be pressured to buy "trusted" computing systems so you don't want them to produce any. This can bring consumer power to bear. If you do this on your own, please send copies of your letters to the organizations above.

17 您也可以经由撰写给 Intel 、 IBM 、 HP/Compaq 或任何您从他那里购买电脑的人, 解释您不想要被强迫购买“可信赖”的计算系统, 因此您不希望他们制造任何这样子的系统。 这可以带给消费者维持〔自由〕的力量。 如果您自行采取行动, 请将您的信件副本送到上述的机构。

后记

  1. The GNU Project distributes the GNU Privacy Guard, a program that implements public-key encryption and digital signatures, which you can use to send secure and private email. It is useful to explore how GPG differs from treacherous computing, and see what makes one helpful and the other so dangerous.

    18 GNU 工程散布了 GNU Privacy Guard (GNU 隐私守卫), 那是一个实现了公开键加密(public-key encryption) 以及数位签章的程序, 您可以使用来送出安全且秘密的电子邮件。 浏览一下 GPG 是如何与「背判了的计算」不同是有用处的, 并且看看那些对於某人有帮助的事物〔为什么〕对其他人是如此的危险。

    When someone uses GPG to send you an encrypted document, and you use GPG to decode it, the result is an unencrypted document that you can read, forward, copy, and even re-encrypt to send it securely to someone else. A treacherous computing application would let you read the words on the screen, but would not let you produce an unencrypted document that you could use in other ways. GPG, a free software package, makes security features available to the users; they use it. Treacherous computing is designed to impose restrictions on the users; it uses them.

    19 当某人使用 GPG 送给您一份加密的文档, 并且您使用了 GPG 来将它解码, 〔所得到的〕结果是一份您可以阅读、〔进一步〕传递、 复制甚至再次加密并安全地送给某个其他人的解密文档。 一个「背判了的计算」应用程序将会让您在萤幕上阅读这些文字, 但是不让您〔能够〕制作出一份可以让您以其它方式使用的解密文档。 GPG 这个自由软件包, 让「安全的功能特色」可以为使用者所取得; 他们使用它。 「背判了的计算」则是设计来将限制加诸到使用者身上; 它利用了他们。

  2. Microsoft presents palladium as a security measure, and claims that it will protect against viruses, but this claim is evidently false. A presentation by Microsoft Research in October 2002 stated that one of the specifications of palladium is that existing operating systems and applications will continue to run; therefore, viruses will continue to be able to do all the things that they can do today.

    20 Microsoft 简报了 palladium 作为一种安全手段, 并且宣称它将会保护〔电脑〕免受病毒的侵袭, 但是证据显示这项宣称完全是站不住脚。 由 Microsoft Research (研究部门)在二○○二年十月所作的一场简报, 说明了 palladium 的其中一项规格是: 现存的操作系统以及应用程序将会继续地采用; 因此, 病毒也将能够继续地做它们今天能做的所有事情。

    When Microsoft speaks of "security" in connection with palladium, they do not mean what we normally mean by that word: protecting your machine from things you do not want. They mean protecting your copies of data on your machine from access by you in ways others do not want. A slide in the presentation listed several types of secrets palladium could be used to keep, including "third party secrets" and "user secrets"--but it put "user secrets" in quotation marks, recognizing that this somewhat of an absurdity in the context of palladium.

    21 当 Microsoft 在谈论到与 palladium 作连接的“安全”时, 他们指的「并不是」我们通常用来表示那个字的意思: 保护您的机器,使其免於受到您不想要〔的事物侵扰〕。 他们指的是保护在您的机器上的您的资料的拷贝, 使其免於被您〔自己〕以其他人不希望的方式进行存取(access)。 简报中的一个幻灯片列出了数个 palladium 可能用来维护的秘密类型, 包括了“第三团体(third party)的秘密”以及“使用者的秘密” -- 但是它将“使用者的秘密”放到引号中, 「似乎」将它认知为: 就 palladium 的〔开发〕脉络而言, 这实在有点荒谬。

    The presentation made frequent use of other terms that we frequently associate with the context of security, such as "attack", "malicious code", "spoofing", as well as "trusted". None of them means what it normally means. "Attack" doesn't mean someone trying to hurt you, it means you trying to copy music. "Malicious code" means code installed by you to do what someone else doesn't want your machine to do. "Spoofing" doesn't mean someone fooling you, it means you fooling palladium. And so on.

    22 简报中频繁地使用当我们谈到安全时, 经常会使用到的其它字眼, 像是“攻击”(attack)、 “恶意的代码”(malicious code)、 “欺骗”(spoofing)以及“可信赖的”(trusted)。 〔但是〕它们之中没有一个指的是我们通常用来表示的意思。 “攻击”并不是指某人试图要伤害您, 它是指您试图要复制音乐; “恶意的代码”指的是由您〔自己〕所安装的代码, 而这代码可能做得出某个「其他人」不希望您的机器去做的某些事; “欺骗”并不是指某人欺骗了您, 它指的是您玩弄了 palladium 。 诸如此类……。

  3. A previous statement by the palladium developers stated the basic premise that whoever developed or collected information should have total control of how you use it. This would represent a revolutionary overturn of past ideas of ethics and of the legal system, and create an unprecedented system of control. The specific problems of these systems are no accident; they result from the basic goal. It is the goal we must reject.

    23 由一个 palladium 开发者先前所作的声明, 说明了它的基本根据是: 不论是谁开发或收集了信息, 应该都对「您如何使用它」具有完全的控制权。 这是对於过去「伦理」和「法律体系」的观念的一种革命性的推翻, 并且创造了一种前所未见的控制体系。 〔关於〕这些系统的特定问题并不是出於偶然; 它们是来自於〔有意识的〕基本目标。 而这目标正是我们必须拒绝的。

Copyright © 2002 Richard Stallman.

Verbatim copying and distribution of this entire article is permitted without royalty in any medium provided this notice is preserved.
【本文允许在无须支付版税, 且不变更文档内容的前提下刊登在任何形式的媒体中, 但需保留此声明。】

prev: RHCE 实践练习(2004.5.17~31)

1. 排错
(1) kickstart 安装;
. 将 ks.cfg 文件放在本地或安装启动盘上,再在 ks.cfg 中指定使用网络安装也是可以的:
nfs --server 192.168.x.x --dir /PATH # 放置 iso 文件的目录
在安装系统的过程中十几分钟的时间怎么利用?

(2) rescue 模式的使用;

(3) 启动问题:
a. 熟记启动的详细过程,清楚各个环节:

Initrd

名称
initrd -- 由启动加载器进行初始化的RAM DISK

描述
/dev/initrd这个特殊文件是一个只读的块设备文件。/dev/initrd设备文件是一个在内核被启动之前由启动加载器进行初始化的RAM disk。

随后,内核利用/dev/initrd设备文件的内容进行两个阶段的(系统)自举。

在(系统)自举的第一个阶段,内核进行初始化,根据/dev/initrd的内容挂载一个原始根文件系统。

在第二个阶段,一些附加的驱动或者其他模块从原始的根设备中被加载。在加载完附加模块后,一个新的根文件系统(也就是常规的根文件系统)从别的设备被挂载。

自举操作流程
使用initrd进行系统自举,系统初始化如下:

1.启动加载器把内核程序以及/dev/initrd的内容加载到内存

2.在内核初始化过程中,内核把/dev/initrd设备的内容解压缩并拷贝到/dev/ram0设备上,随之释放被/dev/initrd占用的内存空间

3.接着内核以可读写的方式把/dev/ram0设备挂载为原始的根文件系统

4.如果(不知道如何翻译indicated)常规根文件系统也是原始根文件系统(举例来说,/dev/ram0),那么内核跳至最后一步正常启动

5.如果可执行文件/linuxrc存在于原始根文件系统上,/linuxrc就以uid为0的帐户身份被执行。(/linuxrc文件必须具有可执行属性,它可以是包括shell脚本在内的任何有效的可执行文件)

6.如果/linuxrc没有被执行或者当/linuxrc(的运行)终止时,常规根文件系统被挂载。(如果/linuxrc退出时在原始根文件系统上挂载了任意文件系统,那么内核的行为则是不定的。阅读注意事项以确定当前的内核行为)

7. 如果常规根文件系统存在/initrd目录,那么/dev/ram0将从/移动到/initrd。否则如果/initrd目录不存在, /dev/ram0将被卸载。(当从/移动到/initrd而/dev/ram0没有被卸载时,会导致进程仍能从/dev/ram0运行)。如果 /initrd目录不存在,并且当/linuxrc退出时任何进程仍能从/dev/ram0运行,内核的行为是不定的。阅读注意事项以确定当前内核的行 为。)

8.正常的启动过程(比如/sbin/init的调用)将在常规根文件系统上进行
...
注意事项
1.在当前内核下,当/dev/ram0从/被移动到/initrd时,任何已挂载的文件系统依然能被访问。然而,/proc/mounts条目不会被更新。
2.在当前内核下,如果/initrd不存在,如果/dev/ram0被其他进程使用中或者有任何文件系统被挂载其上,/dev/ram0将不会被完全卸载。如果/dev/ram0没有被完全卸载,那么/dev/ram0将驻留在内存

也 就是说,因为模块都编译在 /lib/modules/$(uname -r) 中,在内核启动时,一开始是没有办法挂载 / 分区的,而如果这时有一些内核选项如 SCSI 硬盘等编译成了模块,不使用 initrd 就没有办法加载了!另外,如果内核太大,既影响性能,又不利于备份。如果挂载的原始文件系统也是最终的根文件系统,系统将跳过initrd处理而继续正常 的初始化过程。


创建 /dev/initrd 文件的命令:
# mknod -m 400 /dev/initrd b 1 250
# chown root:disk /dev/initrd
要使用 initrd,编译内核时必须选择以下两项:
CON-FIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
即 RAM disk driver 不能作为模块加载。

想知道你的initrd.img中包含了哪些驱动程序吗?
# cat initrd.img | gunzip > /tmp/myinitrdfs
# mkdir /mnt/tmp
# mount -o loop -t ext2 /tmp/myinitrdfs /mnt/tmp
然后查看 /mnt/tmp 中的文件 linuxrc 中的内容即可知道启动时会装入哪些驱动程序。

你也可以更改其中的内容,假设我们想加另一种 SCSI 驱动 aic7xxx.o 进入你的 initrd.img:
# cd /mnt/tmp
# vi linuxrc 加上一行 insmod /lib/aic7xxx.o
# cp /lib/modules/`uname -r`/scsi/aic7xxx.o lib/
# cd /
# umount /mnt/tmp
# dd if=/tmp/myinitrdfs | gzip > /boot/initrd2.img
至此,新的initrd文件initrd2.img就包含了aic7xxx的驱动程序了。

http://www.linuxsir.org/bbs/showthread.php?t=113586

b. 在启动时注意出现的问题,查看启动信息;

c. grub 和 lilo 的使用和排错;

d. 一些启动的关键程序和文件被替换或丢失的情况:如 /bin/mount, /etc/inittab;

(4) 分析系统日志及系统监视:了解一些关键应用和服务在什么日志文件中,及如何使用 logwatch;
. iptables 可以使用如下方式进行日志记录:

modprobe ipt_LOG
... -j LOG --log-level 0 --log-prefix "STRING: "


(5) X Window 排错;

(6) 系统排错一般思路;
/etc/securetty root 可以登陆的终端!

2. 网络架设:
(1) 编译内核;
System.map 是内核符号表,然而很多文档提及,它并非用于内核,换言之,内核不需要它来确定函数位置;它大多用于 log 工具以及调试工具。

(2) ssh,注意结合 X Window;

(3) NIS:注意 auotfs;

3. 其他:
(1) 所有在线文档的查阅!