wpe7.jpg (11495 bytes)

我的征尘是星辰大海。。。

The dirt and dust from my pilgrimage forms oceans of stars...

-------当记忆的篇章变得零碎,当追忆的图片变得模糊,我们只能求助于数字存储的永恒的回忆

作者:黄教授

二〇一四


一月三日 当前只有等待等待

世间的事情就是一层窗户纸一捅就破。关于gsoap的多个wsdl分别编译多个模块使用namespace的c++的链接错误是这样解决的,gsoap的document说的很清楚, 我只是不理解而已。最关键的是要用-CS开关编译一个可以是空的头文件来产生共用的serialization。编译stdsoap2.cpp的时候要使 用-DNO_NAMESPACES的开关,很明显的需要单独编译这个.o供以后的链接。就这么一个关键的地方,当然不明白也就没办法了。

我对于多个wsdl并集的做法一直很抵触的原因是产生的代码文件非常大,很不好管理阅读。但是将多个wsdl分别编译是需要一点点的know- how的,比如,使用一个空的env.h编译开关用-CS  -penv这样子的头文件envH.h必须是你的主代码的第一个include的头文件,否则很多的问题,如SOAP_OK没有定义之类。那么你在编译的 时候namespace需要解决,使用纯c的编译是偷懒的做法,虽然简单算不得好汉,soap2cpp2 -n -i -x -w  -QmyName  myName.h中使用-n是一个关键,否则总有一些问题,但是要注意你就不能再用-lgsoapssl++的动态库去链接了,因为会有 namespace未定义的链接错误,这个要怎么解决呢,查看代码stdsoap2_cpp.cpp里看到"WITHNO_NAMESPACES"的宏需 要定义,所以,你要直接编译这个代码文件同时加上-DWITHNO_NAMESPACES的宏定义开关来编译主的文件。其次看看doc知道你需要在soap_init之后调用soap_set_namespaces把你的独特命名的namespace设定,因为如果没有使用-n的话所有的namespace全局变量都是命名为namespace的,这个在*.nsmap里可以看到。
为了在本机运行server我需要一个最简单的cgi的webserver,于是选择lighttpd,编译的时候我只能禁止pcre和bzip2,主要 是配置文件的设置花了我一点时间,结果我依靠include debug.conf把debug开关都带开看到了参数才明白需要把cgi-bin放在htdoc的目录下才能调用cgi。


一月四日 当前只有等待等待

我的ubuntu10.04的屏保程序老是死机或者不响应,只好从另外一个tty登录kill screensaver,但是上一次用sudo kill好像引发了问题,也许是本身屏保导致的其他问题也不知道,总之很可能是和电源管理有管的问题吧?

一月六日 当前只有等待等待

总结一下:
service=weather
1. touch env.h
2. wsdl2h -qWeather  ./weather.wsdl -o weather.h
3. soapcpp2 -CS -penv env.h
4. soapcpp2 -n -i -w -x -C -QWeather -pWeather -I/gsoap/import ./weather.h
5. g++ -g -DWITH_NONAMESPACES /gsoap/stdsoap2_cpp.cpp WeatherBasicHttpBinding_USCOREIWeatherForecastServiceProxy.cpp WeatherC.cpp WeatherMain.cpp envC.cpp -o weather.exe


一月七日 当前只有等待等待

昨天有很多事情,首 先是openssl的链接问题,日本的lib需要链接老版0.98,而我的gsoap需要1.0版,这个本来没有什么问题,编译过程就能知道,因为强制链 接0.98会爆出链接错误,比如有四个和dh相关的函数未定义,只有链接1.0版才正确,使用ldd检查
编译结果发现确实依赖的是1.0版,这个问题其实我老早就专门解释实验验证过了,就是说在链接过程中实际上是.so文件的所谓的soname被当作了运行 期的动态库的名字,所以,在链接过程中链接的动态库不会因为运行环境存在多个版本的动态库而混乱。但是这个信念昨天被挑战的原因是我在自己实验的 gsoap客户端运行正常但是在集成进工程内的编译运行会爆出一些warning都是服务器证书自签名不可靠的,这个和你使用浏览器访问https网站服 务器证书不是正规签名的警告一样的,问题是为什么会有呢?跟踪发现是因为一个编译宏被打开导致SOAP_DEBUG这个开关打开才打印的debug信息。 其实在编译过程中也遇到不少问题,就是我希望使用根目录的Makefile.inc的一些定义,就在我的子目录里定义include ../Makefile.inc,然后再下面的子目录也这么作,结果就会出现所谓的open too many files的错误,实际上是递归死循环的打开无限次文件,因为relative path这里是错误的,不能有两级这种Include。看代码里面才意识到别人的做法确有独到之处,比如接口定义问题,实际上block和file两个存 储系统接口差别非常大,根本不好去作什么继承,那么我其实一直恍惚怎么作,才发现他们被定义在不同的namespace,所以接口名称一样其实根本不同, 仿佛根本就是两个不同的接口,但是依赖namespace的区分让他们都命名为相同的接口名字确实对于用户有好处。


一月九日 当前只有等待等待

昨天有很做了很多的工作,gsoap里面的namespace很麻烦,我花了好多时间才做到以下
1. 在wsdl2h里要加上-n的开关,这个namespace是web的不是c++ class那块的,我后来使用了一个模板类来把它作为模板参数。
2.suse11.3的编译有些罗嗦,首先要先安装openssl和zlib,都要设定为--prefix=/usr,其次编译过程中需要-ldl。
3.gsoap里的extras的头文件也需要。


一月十三日 当前只有等待等待

唯一值得记录的是如果你不设定init_soap使用keep-alive的话就意味着你每次的调用都要destroy/end,这个问题表现的当然是所谓的第二次的调用出现ssl的错误,不过这个迷雾仅仅让我头疼了几个小时而已。

一月十六日 当前只有等待等待

改明代高启的《题宫女图》诗,《青楼女图》:闺蜜扶醉踏青苔,夜宴陪酒伴月还,小犬隔门吠清影,夜深院寂疑客来。

一月二十日 当前只有等待等待

今天编译静态库发现 了我的一个错误认识,就是能否把多个静态库集成一个大的静态库呢?答案是至少linux不行,你只能用ar把obj编译成静态库。我之前对于编译静态库有 一种畏缩心理因为总是担心链接的问题,其实哪怕你的静态库里有模板类,只要你在适当的地方作Instantiate的话链接并不是问题。当然你直接编译成 动态库的话,链接的问题直接就暴露因为它有链接的过程,对于ar来说就是简单的“拼接”而已。

发现了一个普遍的错误,你能否看到以下的问题呢?这个东西我在cisco就遇到过类似的错误。这里的错误就是dependency的错误,修改其实简单,不过有些tricky。

%.o: %.cpp
    $(CC) -c $(CFLAGS) -o Release/$@ $< 
正确的应该是,这个东西通常都会有一个.o文件的集合,所以以上编译都还是正确的,因为无条件执行,原因是你永远都不会去检查Release/a.o对于 a.cpp的时间依赖关系。有人也许会说无非就是效率问题,编译照样进行并没有错误,可是在某些条件下这个看似无害的错误却是大的问题。比如我的模块需要 特殊的CFLAGS,我本来不想使用其他模块的CFLAGS,但是无意中include了这个编译条件,结果在我的模块中如果对于某个.o没有我自己的编 译指令就会执行这个默认的编译命令,这个时候造成的错误有时候是非常难以发现的,因为很可能你的特殊的flag并不是总是容易发现没有被使用。
Release/%.o: %.cpp
    $(CC) -c $(CFLAGS) -o Release/$@ $<

一月二十四日 当前只有等待等待

当我的链接出现错误,解决的办法是把-lssl -lcrypto移到编译命令的末尾说明了什么呢?我安装的openssl的编译默认选项是静态库,这个特点使得链接的顺序成为了问题。

二月二十日 当前只有等待等待

好长时间没有写日记了。
1.昨天把代码误删除了,于是下载photorec来恢复,这个东西非常棒,你可以选择什么样的文件来恢复,所有的c/c++都恢复成.c文件,这个是可 以在file option里选择的。回复的文件最好是在另一个partition否则有可能影响文件回复。我恢复了几万个文件有上千个文件夹,这个还仅仅是txt文 件,如果不这样过滤还不知道需要多少空间,我趁机把公司NAS的nfs export的文件系统mount到我的开发机器,这个真快真棒。面对这么多的文件搜索是很头疼的,因为普通的命令通常会arguments too long失败,所以这么作一个循环(for i in recur*; do rm $i/*.txt; done)然后你再grep就容易多了(for i in recur*; do grep -r MyKeyWord $i; done) | tee report
2.前天被一个低级问题折腾的够呛,我在定一个namespace的时候忘记了关闭大挂号,结果就出现了形形色色的怪诞的问题,最后还是vampire帮 助找到了原因,这个小子真实聪明。所以,原则是这样子的,首先对于头文件绝对不要使用using namespace,因为Namespace是非常的nasty无法去除。因此,在头文件里所有的symbol都使用全namespace标记,比如 ns1::ns2::type1 ns1::ns2::sym2;在cpp文件里倒是使用using namespace很方便。之前对于这个不是特别的明确,这次吃亏就记忆深刻了。
3. 之前的动态库编译没有添加soname的参数,你需要给linker加参数 -Wl,-soname,libMyLib.so.x.x  这里的x.x就是你的版本号,这样子你的soname将来就作为文件名在运行期来搜索文件了。
4. 之前的在Release/*.o无法实现依赖关系的问题其实很简单,就是我之前在cisco就坐过了,比如
Release/*.o: %.cpp
    $(CC) -c $(CFLAGS) Release/$(shell basename $<) -o Release/$(shell basename $@)
5.今天被python版本折腾了许久,我之前不小心错误的安装了python2.7在redhat6.3上,导致yum不能运行,因为 /usr/bin/yum是一个python的壳子调用真正的yum,于是我请教同事发现rpm -q返回了官方只支持python2.6.6,这就是import yum失败的原因。那么我怎样下载需要的python2.6.6的rpm呢?我去redhat的官方网站使用我们的注册用户登录却无法搜索到相应的 rpm,同事给了一个ftp: //ftp.redhat.com/pub/redhat/linux/enterprise/6Server/en/os/SRPMS可是这里都是 src rpm,后来他有给我一个oracle的http://public- yum.oracle.com/repo/OracleLinux/OL6/latest/x86_64 ,不过不管我怎么安装都报错,现在看来是错误使用64bit版本造成的,应该使用http://public- yum.oracle.com/repo/OracleLinux/OL6/latest/i386/ 当然有意义的是当你强制安装rpm -i --replacepkgs的时候说conflicting就要警惕了,我的情况是代码完全不兼容的64版本。当然我却使用rpm2cpio扣除了 python的binary然后直接替换python2.7似乎解决了问题我觉得问题可能更大了,怎么可能64bit和32bit一样呢?可是我下载了 32bit版的确是和64bit一样。

二月二十二日 当前只有等待等待

我对于网络非常的不 熟悉,比如,我无法上网,但是路由器链接Internet正常,也显示我的电脑也连接上了,但是我无法ping到gateway,尽管我可以使用 dhclient更新我的dhcp的记录,同时我的无线网卡可以上网,同时通过有线连接我居然可以访问router的gui管理网站。这说明了神魔呢?说 明了我的电脑在防火前后面。这个正如你可以链接到Internet但是却无法访问网页也许是你的dns server设置失效一样。同样的,我的amule长久依赖都是显示low ip,随便google都告诉你要作port forwarding,这个是多么简单的配置我却一直不知所以然。说白了就是在router的配置上射了一个Policy需要在指定 ip/application上作端口映射,就是说external的port要映射到一般一样的端口。
二月二十三日  当前只有等待等待
我的Ubuntu系统已经挺乱了,意思是package broken的太多了,这个是难以解决的问题,除非我当初下定决心绝对不更新,可是那个时候我还不懂。所以在安装编译libmicrohttpd的过程中 需要用到的curl/gnutls之类的我都只好是用最新的源代码编译,结果就导致了系统的Lib比较旧,那么我安装的都是小心翼翼在 /usr/local/lib那么当我运行libmicrohttpd的例子的时候,我才发现他的可执行都是一些脚本,example的代码仅仅编译为. o文件,在运行例子的脚本里要和libmicrohttpd的lib链接,稍稍想一下就不应该感到大惊小怪,所谓的开发都是做回调函数,这个在主流如 apache之类都是用插件机制,可是在非主流的强调效率资源的web server肯定要重新编译了,那么怎么才能找到我的非正规的安装的libgnutls库呢?使用LD_LIBRARY_PATH临时设置当然没有问题, 可是多麻烦啊。所以,google就知道机制是这样子的,/etc/ld.so.conf里定义了需要寻找的库的路径,但是这个文件是一个躯壳,仅仅定义 所有定义文件的路径在/etc/ld.so.conf.d/*.conf于是,我需要定义我自己的 /etc/ld.so.conf.d/libgnutls.conf文件列明我的库的路径。当然你修改的要立刻生效需要调用ldconfig来更新。原来 就这么简单,我以前只是模模糊糊的理解。
微信群里在讨论《纸牌屋》,读了Netflix的大战略多少有些好奇,曾经买过全套的《west wings》却连一分钟也没有看过,也许是因为盗版吗?我想不是把,于是从电驴上准备下载,可是多慢啊,发现netflix只要再用一个email,一个 信用卡就可以免费看一个月,为何还要盗版?省了7.99刀还是正大光明的,谁还稀罕盗版,只不过我的smartTV却生生的记住了我之前的帐号无法添加新 的身份,同样的我的linux+fireforx/chromium也无法观看,那么只好使用galaxy note原因是我今天终于幸运的摔坏了我的galaxy s3,很高兴的准备专程t-mobile的Prepaid,好笑的是这一切发生在我去T-MOBILE之后发现他们的计划是一个骗局,我只有自己在网上申 请的才值得,然后我就高兴的不小心的有意无意的摔坏了我的手机以便能够购买一个新的。
整晚的看《纸牌屋》,比较喜欢的是那种一路睡过去的女人,非常的进取,也许这正是我所缺少的。

二月二十五日 当前只有等待等待

《纸牌屋》太过于小资了,太过于左翼与自由派了,我常常纳闷为什么副总统拜登没有像以前那样活跃,也许是看了这个电视剧的关系,想要避嫌?

二月二十七日 当前只有等待等待

昨天在rhel6.3上发现居然没有cmake,结果使用yum总是报错,检查发现package的cache都没有建立,google总觉得是安全的问 题,不得要领,后来发现redhat的package居然是从fedora来的,而我之前在redhat网站下载rpm居然有找不到需要到oracle的 网站才能下载到?!你觉得混乱吗?好端端的东西被oracle收购了就乱七八糟了,然后当然就很简单了,我的http_proxy没有设置 https_proxy,所以才无法在防火墙后面直接使用yum,就这么点事情折腾半天。

二月二十八日 当前只有等待等待

在头文件里定义的array是一个非常的generic的,之所以不使用stl的vector据说原因是多平台编译的问题,但是在骗过编译器的同时给我编程造成很多的困扰,我在很多时候还是用stl的vector于是来回的拷贝很繁琐。
template<class T>
class MyArray
{public:
typedef T element_type;
void push_back(const T&);
size_t size()const;
T operator[](size_t);
};
那么我想再写一个模板类来拷贝:
template<class Array, class Element_Type, ElementType (*callback)(const typename Array::element_type&)>
void array2vector(const Array& array, vector<Element_Type>& vect)
{
    for (size_t i = 0; i < array.size(); i ++)
    {
       vect.push_back(callback(array[i]));
    }
}
你是否注意到了类似stl代码常有的typedef T element_type? 这是因为我要定义一个回调函数或者说函数指针"callback",一个constructor之类的adaptor的functor。请特别留意 typename的使用,在回调函数的定义里你使用的Array::element_type是一个不是模板参数出现的类型,同时也不是普通的 primary的类型,你不给编译器提个醒的话它就不认得了,所以这里typename是必须的。同时我一直想用typedef 来简化函数指针的类型的定义,可是这里用到了模板类的类型我无法预先定义(那样子就是一种specialization,至少是partial的)所以, 你不能在template以外预先定义typedef函数指针的类型,比如typedef ElementType (*CallbackType)(const Array::element_type&);这个语句需要的ElementType是模板类的参数,同时你也不能把这个typedef放在array2vector之前,编译器也不接受,所以,你只能使用这个原始的函数指针的形态。
你看懂了吗?

三月三日 当前只有等待等待

这个兄弟有一个demo是关于restful api的,有时候我也是糊涂,对于一个git,我只想下载某一个部分,这个怎么可能?clone总是要从根部开始的呀。 这个需要用到两个lib,一个是boost 1.41或者更新,我的Ubuntu10.04恰恰好是1.40,刚好没有需要的property_tree,于是我就下载了1.53,其实什么版本都无 所谓的,只不过boost使用b2命令编译,其中用到bz2这个lib,我的ubuntu官方没有,我去下载bzip2.org 可是不知道为什么1.06版居然没有动态库?只好使用1.05版。我选择boost安装路径在/usr/local
以避免冲突,这里又要重温一下动态库编译的问题:系统同时有两个版本的动态库,linux很聪明的使用库里的内嵌的SONAME来决定运行期加载文件,比 如我在编译器设定了-L/usr/local/lib,那么链接就是使用了内嵌soname为libboost_regex.so.1.53.0
objdump -p /usr/local/lib/libboost_regex.so |grep SONAME
  SONAME               libboost_regex.so.1.53.0
那么我的可执行程序就打伤了“烙印”,把这个soname当作“运行期”的“文件名”告诉ld在loading的时候寻找文件名如 libboost_regex.so.1.53.0的程序,这是一个多么号的机制啊,你现在明白为什么有的动态库安装的时候甚至不屑于创建软连接,因为如 果某些特定的程序使用特定版本,根本不需要使用不带版本号的软连接来搜索而直奔主题了。另一个库当然就是libmicrohttpd了,基本上你就是对着 它写回调函数来Handle那些http的请求。另外一个有趣的事情是,运行库的daemon函数是不需要root权限来调用运行的,反正你也不需要往/ 目录下写东西。netstat --listen总之这个是一个很好的关于rest的向导例子,说明了所谓的rest有多么的简洁容易,相比soap的话。
上班可能发现了长久以来的coredump的原因,这个是因为当你的exception在unwinding stack搜寻exception handler的时候,如果你有另一个意外的exception触发的话,(比如在栈里的临时变量的destructor抛出的异常)那么这个 exception是无法被捕捉的。


三月六日 当前只有等待等待

我把openssl编译成静态库加到我们的library里这样省的用户安装,其中需要所有的头文件,这命令很有用,把crypto目录下所有头文件都连同目录结构都拷贝,相当于distcopy:
find crypto -name "*.h" | xargs  -n1 -i  cp --parents -a {}  ~/work/trunk/external/openssl/rhelx86/6.3
关于nested exception导致try-catch失败的例子在这里,这就是coredump的模型。这里是这个例子的来源,我现在的实践经验是stackoverflow.com是程序员最值得信赖的网站,不论多么复杂难见的问题都有人在这里得到解答。
//============================================================================
// Name        : myThrowTest.cpp
// Author      :
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/exception/exception.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/exception/enable_current_exception.hpp>
using namespace std;

class A
{
public:
    typedef boost::shared_ptr<A> ptr;
    A(std::string name = "default") :
        m_name(name)
    {
    }
    void throwInDestor()
    {
        if (m_name == "throwInDestructor")
            throw 34;
    }
    ~A()
    {
        throwInDestor();
    }
    ;
    void throwName()
    {
        throw m_name;
    }

    std::string m_name;
};

void callfunc(A::ptr a)
{
    a->throwName();
}

void callf1(A::ptr a)
{
    A::ptr b(new A("throwInDestructor"));
    callfunc(a);
}

void callf2()
{
    A::ptr a(new A("call2"));
    callf1(a);
}

int main()
{
    try
    {
        try
        {
            callf2();
        } catch (...)
        {
            std::cout << "inner: " << boost::diagnostic_information(
                    boost::current_exception()) << std::endl;
        }
    } catch (...)
    {
        std::cout << "outer: " << boost::diagnostic_information(
                boost::current_exception()) << std::endl;
    }
}


三月十一日 当前只有等待等待

svn使用其实要比git来的复杂,亦或许我对于git的高级功能还不知道?在一个repositary里引用另一个这种做法也是常见的,结果是让你不能 轻易删除。可是我的情况不同,我打算删除的是我自己以前加进去的,删除后commit总是报错说lock token not available,在本地cleanup无效,后来只好转到windows使用tortoise,图形界面的菜单有一个check for modification里出现我删除的内容,有一个check repositary的按钮发现那些lock是在服务器远程,然后图形界面是由一个release lock的功能,这个怎样在命令行来做我还真的一无所知。
那么之前我在gsoap上出现的coredump是怎样临时workaround的呢?我的奇怪的coredump发生在我使用一些gsoap产生的 xxx_request, xxx_response来呼叫web service的api,然后遇到错误我抛出一个exception来返回错误代码,这个似乎是通常的做法,但是问题在于异常在unwinding stack的时候需要呼叫所有的stack内声明的临时变量的destructor,而如果这个时候gsoap内部alloc的heap内存有 corruption之类的抛出另一个异常则导致c++异常处置代码无所侍从唯有signal一个退出,这样子才会发生我的catch(...)无法捕捉 的coredump。那么我的解决办法是一个掩耳盗铃的临时做法,就是在我抛出异常前我先把我的gsoap的变量释放掉,这样子抛出异常不会有gsoap 的干扰了,当然我必须把stack的临时变量改为heap的动态分配的。这个是不得以的办法,因为让我去追踪gsoap的代码的缺陷实在是力不从心,我尝 试过感觉不是那么容易,否则也轮不到现在了,就是说如果是明显的问题早就解决掉了。
寻找回忆

三月十八日 当前只有等待等待

当那些精英们在谈论风花雪月的时候,当那些人妻人母们在唠奶奶经的时候,我在为那个core dump伤脑筋。这就是世界的差别。gsoap的gpl v2的license有可能要了我的命,因为我不知道是否还存在一个c/c++的生成soap的客户端的工具。

三月二十二日 当前只有等待等待

hitachi的存储系统接受的参数需要一个结构来作传入传出,那么这个结构需要清零,我就写了一个宏:

#define STRUCT_CLEAR_MEMBER_AFTER(ptr, member) \

                if ((ptr)) {                             \

                                size_t size = sizeof(*(ptr)) - ((char*)(&((ptr)->member))-(char*)((ptr))); \

                                memset((char*)(&((ptr)->member)), 0, size); \

                }

有错吗?我看不出。
现在比较理解为什么这个rmlib不对外开放,因为它太接近底层的寄存器代码了,说他是汇编的c调用也不为过,因为就是真正的syscall的模样。

三月二十七日 当前只有等待等待

以上那个STRUCT_CLEAR_MEMBER_AFTER的宏居然在windows下会corrupt内存,原因何在呢?令人难以思议,唯一的猜测是 hitachi的工程师的帮助,那个跨平台的大一统的参数结构(512bytes)的一个结构居然不给你使用#pragma pack(1),也就是说每个平台的每个编译器都按照本地的alignment来定义那个结构的大小,比如正常的编译器设置可能都是alignment= 4的一个byte的成员占4个byte如果这个没有4byte对齐的话。然后好心的hitachi工程师在rmlib里面据说完成endian的变换,数 据的对齐,这个帮助了每个平台的开发者,可是我却没有意识到这个问题。于是想露脸结果把屁股露出来了。
soap可能是一个非常简单的玩意,真的需要gsoap吗?比如 (出于良知,我不应该把敏感数据披露,user/passwd和url不列明了:
<SOAP-ENV:Envelope><SOAP-ENV:Body><HYASVER:getApiVersionResponse><HYASVER:version>1.3</HYASVER:version></HYASVER:getApiVersionResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
这么一个请求你用curl发过去就醒了:curl -k --user "user:passwd" -d @VersionMgmntProviderBinding.getApiVersion.req.xml https://172.17.37.121:port/the/service/url  > response.xml
结果如下(省略soap的垃圾部分): <SOAP-ENV:Body><HYASVER:getApiVersionResponse><HYASVER:version>1.3</HYASVER:version></HYASVER:getApiVersionResponse></SOAP-ENV:Body>
所以需要去做的就是手工调用。

三月二十八日 当前只有等待等待

需要使用一个xml的parser,我讨厌复杂的xerces,因为我的需求有限,就是soap server产生的标准的xml,很规范无复杂的feature,何必需要在引入复杂的编译和license的问题呢?所以我选择了简单的不能再简单的 tinyxml2,他的前身tinyxml我也用过,据说效率是不凡的,因为用回调函数输出能够防止读取巨大xml文件的大内存耗用。不过怎样遍历xml 的节点呢?还是学习了一下,这个是一个DFS,即深度优先的搜索,简单的不能再简单了,我对于soap的xml的结构终于有了第一步的认识,首先 declaration是xml的边准的,然后就是所谓的envelope,里面大体定义了一些namespace,然后在body里面才是根据一个个的 namespace的定义的内容,envelope是body的父亲,而不是兄弟,这个是我没有想到的。
#include "tinyxml2.h"
#include <iostream>

using namespace std;
using namespace tinyxml2;

void doRecurse(XMLNode* node)
{
    while (node != NULL)
    {
        cout << " value:"<< node->Value() << endl;

        XMLNode* sonNode = node->FirstChild();
        doRecurse(sonNode);

        node = node->NextSibling();
    }
}

void test1()
{
    XMLDocument xmlDoc;
    XMLError xmlRes = xmlDoc.LoadFile("request.xml");
    if (xmlRes != XML_SUCCESS)
    {
        cout << " failed " << endl;
        return;
    }
    XMLNode* rootNode = xmlDoc.FirstChild();
    doRecurse(rootNode);
}

四月十一日 当前只有等待等待

回了趟厦门,常常感到无语,因为共产党虽然让我觉得是一个腐朽没落的政党,但是似乎又是一个无可奈何的选择,相信非常多的我的同龄人是这样认为的,至少共产党有意识的让人们这么建立了这么一个观念。
linux设定java还是要小心:
1.小心使用alternative来设定: sudo update-alternatives --config java
2.当然前提是你先下载适当的版本。比如把package安装在/usr/java下面是比较号的习惯吧。sudo update-alternatives --install "/usr/bin/java" "java" "/usr/java/jre1.7.0_45/bin/java"  1064
3.运行.jnlp文件相当与调用javaws。
白天日本方面的email要求紧急把openssl升级到1.01g版,因为那个heartbleeding的bug威胁,我就在我的rhel63编译安 装,其实是想测试一下,结果我自己就再也无法使用ssh来login了,就是rdp也不行,D说还有admin port,大概是远程的RS232通过ethernet的连接吧,但是这个是系统的秘密要申请。
晚上睡不着就下载那个fix来看看,纯粹好奇,当然是似懂非懂,从git log你很容易找到那个fix,参照源码大体就是有人如果用heartbeat的payload做的比较大(超过65535?)结果再回调函数不检查长度 就把超长的buffer写入然后发回?总之,我是没有能力赚这个钱的,还是老老实实领工资吧,因为,这个东西绝对是一个产业链才行,你用这个漏洞能够把大 量的内存信息取出来,还要有人运行分析,就算找到敏感内容还要有人再去套钱出来,而这所有的都是基于海量的爬虫运行的结果,绝非业余玩家能够利用的。

四月十四日 当前只有等待等待

我有些疑惑,以前我设定eclipse里的static library 的linking是使用:/full/path/full/static/lib/name,可是好像不行,现在反而要改为lib path和-lname.
上周我准备升级openssl到1.01g结果导致openssh无法运行,应该是sshd需要链接正确的openssl版本吧,我是完全覆盖?结果导致 我的rhel63完全无法链接,连rdp也不行,真奇怪。正当我一筹莫展考虑只有到数据中心用kvm链接恢复之际,D说有一个秘密通道,他说是类似 rs232的以太网链接,不过我查看了rhel的其他的配置,根本不可能使用telnet的链接,因为端口都被封闭是肯定的,后来techop给了一个 ip让我链接,问了R才知道是怎么回事。supermicro是硬件制造商制造了server,hitachi买了一个blade的空壳子之类在上面放一 个远程kvm,用一个cgi来输出类似rdp的一个东西,这个是一个远程管理blade server的chassie的其中一个小工具,可以通过防火墙全球访问,难怪是秘密通道。不过,用浏览器连接的时候注意要把proxy去除掉,还要升级 java到7.0才行。

四月十七日 当前只有等待等待

运行topcoder的.jnlp程序需要下载java7,安装实际就是把他拷贝到一个固定地方,然后把你需要的java或者javaws 的软连接指向而已。然后运行javaws提示运行那个.jnlp。玩了一会openssl就放弃了,这个我目前玩不动,连证书和密钥都没搞明白怎么运行?
打发时间

四月十九日 当前只有等待等待

打发时间。这个250分的题目我却希望能够找到怎样 实现社会公平正义的计算机的解决办法,问题如下,一个社会的每个成员收入有高有低,一个理想的社会主义者,或者说奥巴马想要让社会人人平等把所有的人的工 资通过征税和补贴的方式让每个人和这个社会的最高收入者的收入差不大于一个很小的数字,比如一万美元,那么问题是怎样计算一个这样的标准收入水平以便让美 国的国税局和社会保障部在对高收入者征税和对低收入者补贴的程序最简单,也就是说高收入征税的总和和低收入补贴的总和加起来最少,那么为了达到“公平社 会”所需要付出的公共资源就最少,浪费最小,影响的社会层面也最小。这就是一个寻找社会收入中位数还是平均数的过程?我想了半天也不确定那种最靠谱,看来 “和平”解决这个问题是没有可能了,对于程序员来说最欣赏的就是“暴力”,我现在非常的恐怖,几乎对于所有的问题都采用“暴力”的解决方案,难道我已经成 为这个社会的不稳定因素了?但是不管怎样从心底里还是要呐喊那句经典:Brute force, I love you! 怎么你不知道我说的“暴力”就是brute force吗?说明你是非计算机专业毕业的。

四月二十九日 当前只有等待等待

我现在还算谨慎,下载zfs编译需要大概是内核的支持所谓的spl的package,我不敢安装,就在configure --with-spl=/my/download/spl/path,这时候zfs的configure抱怨需要libuuid,我没找到开发包就下载 libuuid运行包的源码,apt解决认为下载util-linux的源码捎带附赠blkid的源码,我configure也不敢安装,看起来 uuid.h的头文件没什么花哨仅仅是函数定义,应该无害,编译手动拷贝头文件,动态库不敢拷贝就用系统自己的,甚至都不敢添加不去别soname的 general的软连接,保持系统带版本号的软连接,防止可能的问题,拷贝uuid.pc到/usr/lib/pkgconfig,把lib的路径的 prefix改为空白因为系统的不是在/usr/lib而是/lib,因为这个东西是属于非常核心的util-linux的,印象中你自己制作linux 操作系统的时候这个包是和glibc之类一样的非常非常基本的东西,非常害怕触碰。不过后来还是屈服了不得不加一个libuuid.so.1 libuuid.so的软连接。
找到了一个H*的类似于后门,就是H*组不给你他们内部的webservice,其实端口都是8443,只不过是不同的url,这个是baservice 加上相应的provider,于是我用gsoap把他们内部的.wsdl编译产生req.xml来用curl调用:curl -k --user "***:***"  -d @request.xml https://ip:8443/baservice/**Provider > response.xml,当然调用的时候如果是在lab的network要把proxy去掉,unset https_proxy,我总是忘记得到403的错误还不知道是proxy的问题。
学习一下zfs,这个是文档

五月一日 当前只有等待等待

写makefile曾经被狠狠地折磨过一次,原因其实很简单,就是写一个循环:
ALL_OBJS=$(wildcard *Provider)
all:
    $(foreach var,$(ALL_OBJS),cd $(var); make;)
这里能有什么问题呢?我当时百思不得其解,后来反复debug才发现问题,原来这个是常见的问题,就是关于路径的问题,CD_PATH是一个变量如果没有 正确设定往往cd不能正确执行。所以,我另外定义了一个CWD=$(shell pwd),然后cd $(CWD)/$(var);原来如此。后来我希望用makefile来产生一系列文件,其中要输出makefile,比如要打印$ (ROOT_DIR),这里$和()都是特殊字符,于是要$$输出dollar,但是()会作为变量调用的,因此这样子echo "$$(""ROOT_DIR)=../../.." > $(VAR)
天天加班,无比辛苦,晚上回来累的半死。

五月二日 当前只有等待等待

使用gsoap的人应该都会遇到一个问题是openssl/gnutls的问题,我没有使用config.h而是直接在configure里面定义,后来 在rhel6.3下产生的代码要被用到suse11.3和solaris,现在要用到windows2008了,结果编译方法当然差别很大,我曾经想要使 用nmake来作,但是这个要求原来linux的makefile要和nmake兼容,很不容易,最后才意识到windows的容易不是白说的,你作为开 发者压根不需要操心编译的很多的细节,直接把所有的代码文件通通拉到工程下面就成了。当然我又一次犯了以前的一个错误,话说gsoap使用所谓的 namespace来区别各个定义和函数,这当然是webservice原本定义的,其中对于每一个wsdl文件你可以定义自己的一个struct Name;的实例,也可以使用各个独立的namespace当然需要你事先定义好不重复,总之细节是在struct soap里面有一个所谓的变量struct Name的成员变量,当你定义了使用namespace的时候那个全局变量extern struct Name namespaces[];就不得不定义了,因为有soap.names=namespaces;我当时为此百思不得其解,后来看到它有#ifdef WITH_NAMESPACE才是这样子,而else里是soap.names=NULL;这里就不在需要定义那个全局的extern struct Name namespaces[];说来话长,其实实在不足道,压根儿就是写给自己看的。
( 我在一月三日的日记里写的多么的清楚:编译stdsoap2.cpp的时候要使 用-DNO_NAMESPACES的开关,很明显的需要单独编译这个.o供以后的链接。就这么一个关键的地方,当然不明白也就没办法了。)结果在Port windows的时候全忘记了。我的记忆力真的这么糟糕吗?我很想和我的同龄人来比较一下到底是我的记忆力衰退的太快还是我需要或者我期待记忆的太 多???

五月三日 当前只有等待等待

脑海里经常的一片空白。
昨天去coyote跑步再次给san jose的烂疮拍照:大量的无家可归者在coyote creek河岸秘密的丛林里搭帐篷七夕,和one stone throw away的富裕社区的反差如此的大。不过感叹至于又一次深刻体会当年丘吉尔首相关于社会主义和资本主义两种制度的优劣行的论断:资本主义制度的缺点在于难 以平均全体社会成员的幸福,社会主义制度的优点在于能够平均全体社会成员的痛苦。说的多么的一针见血啊!美国再怎么富裕强大也不可能保证每个社会成员都能 够享受同样的幸福富裕生活,但是社会主义中国却可以轻而易举的剥夺大多数社会成员的财富来进行低水平的平均,难道这个不是说明了在原始社会早期的做法是社 会主义,以便防止部分成员无法保证基本的温饱而病饿死?当社会总体财富增长了就应该施行资本主义的多劳多得?所以,马克思恩格斯当初正好说反了,是资本主 义是社会主义的掘墓人,因为社会主义是步入资本主义的一个充分但并非必要的阶段,一旦社会总体财富能够保证部分病弱成员因丧失劳动力也能够依靠社会救济存 活的时候就应该放弃社会主义而进入资本主义社会?也许中国今天的社会实践就是这个论断的实证。
我快速的浏览了zfs,感觉我唯一感兴趣的就是zil---intent log。纲举目张,有机会比较一下svn/git的jounel的做法,甚至rsync是怎么作的也很有意思,需要学习的太多了,而一个人的意愿与能力是这么的不成正比,这就是人类的悲剧。
看台湾的学生游行学到一个新词:小确信。google了意思是小而确定的幸福。明白了我现在的生活就是小确信,每天有饭吃,有太阳晒,能上网,能开车到处转,偶尔学习一些新东西。

五月五日 当前只有等待等待

一个古老的故事就是老生常谈了,在cisco的时候就遇到,比如你写了一个测试程序需要进行一些系统测试,例如打开系统设备,加载内核模块等等,但是出于 安全考虑不愿意给每个人使用root登录(特别是以前我们希望小组里每个人都用自己的用户登录进行独立测试,有自己的log等等),那么你怎么进行呢?以 前Balaji就反复说使用setuid,我其实只闻其名不明其所以然,也是懒惰这么一个东西几年都没有google读书,今早上看了一下是这样子的,把 我的那个测试程序改成root为owner,同时设置它的setuid bit设置,也就是说当我运行这个程序的时候我的进程的effective user就是这个文件的owner了。而程序执行操作的时候通常是使用effective user来测试权限的。所以,我以为我可以在eclipse里使用debug来这样运行,可是失败了,为什么?这个是gdb的限制吧
这里的解释非常的棒,不过我还需要消化:1.远程debug的技巧主动调用类似于windows的debugBreak。2.gdb只能使用root user运行来作debug,3.使用sudo有弊端是运行环境改变了。

五月十一日 当前只有等待等待

关于rsync的一个rollover checksum的算法是这样子的,我把他们重新定义了一下:
Given a series of byte stream data, define calculation of rollover checksum as repeating calling the following two functions:
1. function: byte_rollover_checksum_fun or BR;  input: previous BR result and current bytes
2. function: rollover_checksum or RC;  input: previous RC result and result of current BR
let br[n] be result of BR of n operations;
let rc[n] be result of RC of n operations;
let data[n] be input byte stream data;

let br[0] = rc[0] = 0;

rc[i+1] = RC(rc[i], data[i+1]);
br[i+1] = BR(br[i], rc[i+1])  ==>  br[i+1] = BR(br[i], RC(rc[i], data[i+1]));
So what???
OK, here is our trick. Let us design our function BR, CR to be "linear functions". (我自己定义的一般性二元线性方程: if f, g are functions and f(g(a,b)) == g(f(a,b))  then f, g are linear function)
We also give a feature of RC and BR such that  RC(r, 0) = r and BR(b, 0) = b. (somthing like an identity property??)
Therefore  br[i+1]= BR(RC(br[i],0), RC(rc[i], data[i+1])  = RC(BR(br[i], 0), BR(rc[i], data[i+1]) = ???
其实我当时就是想去推演一下rollover checksum的公式而已。以后有时间在搞吧。

五月十三日 当前只有等待等待

年纪成为兴趣变化的主因,开始对于文件系统学习,看看btrfs吧,但是需要用到libblkid,以及ext2fsprogs而奇怪的是从它的官方git得到的最新源码居然缺失了很多libblkid的很多新函数,看看这个发布者的博客学习一下吧。编译btrfs的时候需要的library如下
sudo apt-get build-dep btrfs-tools
-or-
sudo apt-get install uuid-dev libattr1-dev zlib1g-dev libacl1-dev e2fslibs-dev libblkid-dev liblzo2-dev
不过我的古董级的ubuntu10.04早已脱离主流了,我无法加载官方的库,只好下载源码编译e2fslibs-dev。
windows 的确是开发者的梦魇,我因为需要使用gsoap的客户端必须要在windows下链接openssl的1.01xx版本,但是原本的库里面已经有用到 0.98的openssl,这个现在无法替代因为是从日本过来的binary,那么在windows下是没有Linux的soname或者软链接之类的, 所以,唯一的办法就是编译openssl把它重新命名.lib来链接。
编译openssl不是一个简单的工作:
1.要使用命令行编译,因此,nmake.exe rc.exe的路径要在path里。(这其中隐含了正确的平台,比如要amd64,你的库和命令行工具都要一致。)2.platform SDK是必须的因为其中的很多头文件是必须要的,因此它的bin也要在path里(主要是rc.exe?)。3.要安装perl,自然要加如到path。 4.产生的ntdll.mak文件不正确,我只好在CFLAGS里把include的platformSDK的include和VC运行库的 include都加入,在自己在link命令后添加/LIBPATH:库的路径,因为LD_FLAGS似乎比起作用。5.在资源编辑器rc后添加/i 把PlatformSDK的include目录也添加。
其实也不复杂,对吗?但是当我改动lib/dll的名称后有一些函数没有正确编译,DH_compute_key之类的缺失了,这个迷惑了半个下午,因为我一直以为我编译的库没有被正确链接。明天要去研读makefile来找原因。

五月十五日 当前只有等待等待

我的ubuntu10.04没有把btrfs内核编译进去,于是需要编译内核模块,最简单的是这样子的:
编译模块
1. make menuconfig把fs/btrfs设定为模块m
2. make SUBDIRS=fs/btrfs modules
部署模块
sudo mkdir /lib/modules/`uname -r`/kernel/fs/btrfs/
sudo cp fs/btrfs/btrfs.ko /lib/modules/`uname -r`/kernel/fs/btrfs/btrfs.ko
加载模块
sudo depmod
sudo modprobe btrfs
关于mount我还有些疑问,在fstab里家了user的option以后mount不需要root,但是mount的dir却还是root的。我存了 一些文件在btrfs上然后想要创建subvolume和snapshot都失败了,我在想ubuntu10.04自带的模块太老了?我已经下载编译了最 新的btrfs那么是否应该加入内核呢?可是现有的内核模块lsmod显示【permenant】,我是否可以卸载模块呢?似乎不行,那么重启吧?我的理 解那个是内核模块内存的管理,并非指内核模块不可卸载?不确定。
晚上回到家看了一下,下载的所谓的btrfs的包好像是命令行工具和运行库,和我的内核的btrfs根本不是一回事的东西,当然我运行这个工具还都正确,之前我使用ubuntu10.04默认的命令行工具总出错。所以,使用官方的内核,使用最新版的工具,很号。

五月二十五日 当前只有等待等待

花了一点时间机械的把ssh2的例子重新组织了一下,结果发现始终在userpasswd_authorization过程很慢,而运行例子非常的快,还以为是什么特殊的原因,后来才发现例子用的是127.0.0.1而我的测试使用的虽然也是本机地址,但是和那个内存里的Loopback比较还是慢的多了。

六月一日 当前只有等待等待

You don't have my respect unless you win it, or at least earn it! In the first case, I yearn to your superiority. In the second case, I yearn to your monetary power.
整天加班非常累,感觉还是不一定能够完成。
记错了一件事,我的comcast的cable modem的ip是192.168.100.1,我一直和以前的att的dslrouter的分配的192.168.1.254混淆起来,貌似那个是我自 己设定的,comcast的这个是固定的,至于说我自己的router的ip纯粹是我自己设定的192.168.1.253,当初是想在转换att和 comcast之间时候不做更动。

六月十四日 当前只有等待等待

加班有时候成为常态了,不过我并没有什么可抱怨的,如果不加班干活也没有什么好干的了。
长久以来我一直有一个谜团,那就是这个网站的编码问题,我曾经用正规的url编码编撰我的中文名字的文件,但是不成功,于是我尝试用iconv来遍历所有的编码结果还是不行,后来使用网站自己的工具来查看文件的名字,请教了V之后才意识到一个常识,就是ascii编码的所谓的html-entity的编码方式,据说这个是为了防止跨平台脚本攻击的,于是写了一个小工具来测试一系列的想法。

六月十七日 当前只有等待等待

一个简单的不能再简单的问题,就是makefile里缅经常能够遇到错误而不停下来的问题,比如 cd abc; make 这就是问题,因为这个要编程cd abc && make就会返回错误,make就会停下来了。
去看<edge of tomorrow>剧情实际平淡无奇,但是其中展现的美军未来作战模式确实实实在在的。

六月二十日 当前只有等待等待

凡事都使用武力来解决是不行的,但是凡事都绝对都不使用武力也是绝对不行的。中共归根结底的本质还是一个腐朽没落的封建帝国,遵循内残外忍是一个基本的治 国原则,而这一切的根本原因一方面是红色恐怖的残暴,另一方面是商民族的一贯的柔弱与逆来顺受。昨天看到一个金融时报的博客引述的传教士利玛窦的话:一个疆域巨大有着数不尽的人力物力和不计其数的军队的泱泱大国的统治者却整天整晚的生活在惶惶不可终日之间,时时刻刻担心着周围小国的侵略与袭扰,担心着手无寸铁的臣民的反抗。
我对于makefile里的.phony一向不大了然,觉得无所谓。结果现在才认识到了它的宝贵,我遇到了一个问题,在makefile里的 foreach循环无法在出现第一个错误的时候停下来,即便使用了cd abc && make;这样子的形式在循环也不起作用,(这里的小插曲是我原本以为是两个语句的问题,于是改成了make -C abc来代替上述的两个语句,结果还是不行。)这个时候才明白了.phony的妙用,也就是如下的样子:
我有大约几十个以provider结尾的子目录,里面每一个都有一个.wsdl,有一堆的功能代码,自然每一个都有一个makefile,于是怎么做呢?
ALL_PROVIDER=$(patsubst  *provider)
.phony: $(ALL_PROVIDER)
ALL: $(ALL_PROVIDER)

$(ALL_PROVIDER):   
    $(MAKE) -C $@
这个就可以保障你的第一个错误就停下来。而这个是不是比之前的foreach来的好看呢?

六月二十一日 当前只有等待等待

埃尔夫仙女对福尔都说:当所有的星星都熄灭的时候,唯一照亮这个世界的光明就是你的心灵。
这里唯一的光明之源就是gnu。
我闲极无聊之际想要试验一下ftp,你说有多好笑,我就是计算机界的考古学家,当人们追捧新鲜靓丽的时候我在故纸堆里寻找往日的辉煌。
实验了libcurl,感觉有毛病,size返回失败550,(后来知道不是curl的问题,而是ascii模式的问题,看这里。stackoverflow真的是人才济济啊。权威!)看了一下filezilla发现它是一个gui,然后才想到了gnu,这个inetutil真好,因为就是这么简单。
我真心实意的热爱gnu。

六月二十二日 当前只有等待等待

我原来对于ftp协议一无所知,所以,在读了一点点wiki才明白我原来想的根本不对,其实,它就是一个在古老年代创建起来的架构,一个一问一答的模式, 所以使用libcurl难怪不好用,因此开发就流于一个命令行解释器了,我很感无聊就不再想折腾了。于是回到以前的那个S3吧。但是发现amazon升级 的很多,现在的S3已经是第四版了,加密方法改了太多太多,看样子要推倒重写了

六月二十三日 当前只有等待等待

我改写的签名有什么地方有错,下载新版的libs3对照,发现也许是一个小问题,基本的数字签名算法并没有改变。重新整理一下。先报存一个版本的libs3作 为参考。有几个基本的无脑级别的comment:所谓的aws的sdk只有windows/java/script之类的,linux是没有sdk的,能 开越野车的人还需要培训驾照吗?这个libs3其实和以前架构没变,依然没有multipart upload因为这个太复杂了,和普通的函数差别非常大,我还是很自豪以前我能够写这么一个,准备调试一下把它整理出来。

六月二十五日 当前只有等待等待

我为了安装打印机驱动结果把整个系统感掉了,这个是我长久以来就期待的吗?折腾吧。
重新编译gcc是第一步,从官方网站下载trunk编译总是有小问题,我的系统的multi-lib总有问题。

六月二十七日 当前只有等待等待

编译gcc需要什么texinfo之类的,忘了,反正要编译multi-lib需要安装额外的32位的包。然后,开始debug出现了这个错误:Dwarf Error: wrong version in compilation unit header (is 4, should be 2),google 之后才意识到是gdb没有与时俱进看来编译器用了最新的gdb也要更新为7.x版的了。编译源码吧,以前在cisco打杂不明白他们为什么自己编译 gdb,看来工欲善其事,必先利其器。学习一下。很有可能是同样的原因,因为新版的编译器解决了很多的问题,那么他们当然希望使用,那么没有选择的要使用 新版的gdb,这个小问题在三年后我才意识到,之前我都仅仅使用4.7版以前的gcc都没有这个问题。

六月二十九日 当前只有等待等待

一个恼人的地方是ubuntu10.04不再有官方的全力支持,新的package大豆不兼容,就是说自动升级导致大批旧的package完全无法安装, 于是我就只好手动一个一个把他们降级以便安装其他依赖的包,甚至像是ext2fsprogs这样的关键包也不例外,我的策略是现在干脆把可能安装的包通通 都安装以至于将来不会再不小心安装错误的新版的包。好累啊。

七月六日 当前只有等待等待

这个东西纯粹是朝花夕拾的性质,几乎是毫无悬念的玩意,我有libs3的源代码,有aws的官方文档,大量的人已经大量的好几年的实践开发,S3又是所有 aws里最成熟的玩意,想不出有什么问题,可是我还是犯了不少的错误,md5不是直接的hex形式要用base64转码,当然这个是document里写 的明明白白的,只是我很奇怪我以前的代码没有这么做,那么究竟是怎么成功上传的呢?总不会是最近才改动的吧?
x-amz-storage-class这个是有效的,不过libs3却把这个放在一个x-amz-meta的后面这个实际上是Userdefined meta亚马逊是不予理睬的。另一个小问题是amazon的etag返回的时候加了引号,结果我比较md5始终都不符合。保存一个版本吧。这个小玩意花了我好几天的时间,其实也做了一些的工作了,我把私人文件的权限修改了。
一开始我还担心我的eclipse里的debug设置会暴露我的s3的key,结果发现eclipse的设计就是周全,这个东西在这里: .metadata\.plugins\org.eclipse.debug.core\.launches

七月七日 当前只有等待等待

学习ext2fs这个听上去像是王朔小说里的那个杀人犯自供书里的不在现场证据的供词,我清楚记得他当时说是在加学习毛主席著作《敦促杜聿明投降书》之类的。

七月十日 当前只有等待等待

这个又是一个笑话,我把content-type和content-encoding搞混了,后者实际是压缩方式,服务器端使用这个,客户端使用accepted-encoding,结果所有的都被当作二进制流设定了。只好全部上传,找不到改动metadata的api。

七月十三日 当前只有等待等待

这个是值得记录的:在HNAS里的所谓ssh有些花哨。实际上我对于screen不熟悉所以不是很清楚究竟发生了什么事情,但是普通的libssh2链接 后得不到运行结果,因为系统不是简单运行bash,而是在一个自定义的Login之后运行一个自定义的命令解释器,所以,在ssh命令里需要 /self/defined/interpreter  actual-command。因为正常你默认使用sh来运行命令。
买了一个行车记录仪,还是很震撼的便宜,46块钱包邮,当然没有压缩,简单的avi文件。玩了一下tpm,这个是例子。

七月十六日 当前只有等待等待

这个是synology的命令表,有点用。也许是实际的bash,但也许是一个自己的解释器,或者更加可能的是裁剪过的bash之类的shell,不过有ssh很方便的。
好像对于这个小小libs3小工具的改造到了一个停止的阶段了。画一个句号。使用的libs3源代码是这里。

七月二十日 当前只有等待等待

这个是一个好东西,读了一点是一点,就好像当初张无忌学习乾坤大挪移一般,在有限的时间能有多少就是多少,学一点也是受用无穷的。实际上我看了没一页就犯困了,为了惩罚自己,我决定在烈日下跑步。

七月二十一日 当前只有等待等待

其实这是一个非常简单的问题,但是我就是一开始不开窍:使用nfs的时候,怎样让Mount的文件及目录是我自己的用户名?多简单的问题啊,之前我使用两 台ubuntu彼此用nfs mount从来没有意识到这是个问题,现在使用synology才发现这个问题,就是这么简单,在synology的nas上的Nfs server上的Nick这个用户和我自己ubuntu上的名字一样却是完全风马牛不相及的,只能用pid/uid来mapping啊,所以,就都改成了 1000.1000,至于server的设置,
cat /etc/exports 
/volume1/DiskStation    *(rw,async,no_wdelay,insecure,root_squash,insecure_locks,sec=sys,anonuid=1000,anongid=1000)
明白了吗?
下载了theodore的文档,似乎很有名的人物。

七月二十三日 当前只有等待等待

其实我加班都是自找的,明明可以早点回家却在办公室里搞一些额外的东西,首先,在64位Linux机器上编译32位的程序就是一个问题,究竟有何益处?应 该唯一的好处就是在一台主机上能够做32/64位的开发编译工作,但是rhel是否有官方的全套的库需要我发现。其次,我遇到一个问题花了一天才明白一点 端倪,就是我的32位的rhel6.3在debug时候,gdb居然占用100%cpu,(当然后来意识到是多核的100%实际上是一个核的100%,不 过没啥区别)我一开始总是以为是程序本身复杂,比如变量多symbol table大?但是后来不再eclipse里直接使用gdb并没有发现这个问题,说明这是eclipse的问题,一开始还以为是memory thrashing,所以在启动eclipse的参数上做文章,实际上我以前就已经设定了jvm的1024M内存的参数,所以并没有什么大的变化。后来发 现并非总是伴随大内存使用,主要是cpu的99-100%的现象,然后就是使用不同版本的eclipse,并升级,依然没有结果,然后观察到在 eclipse的console里显示一个python的函数转换long int时候报错说是integer overflow,现在我在写这些东西的时候有了一个新的想法:在rhel里面gdb/gcc/gdbinit之类的都是一些空壳子,是python的小 脚本包装了一层,说不定出错的是这些壳子,明天去办公室尝试看看,因为经过一天多的排查我已经否定了是操作系统32位内存问题,否定了gdb本身的问题, 否定了是eclipse的版本问题,现在看来说不定是这个gdb python壳子的问题!在这之前我还花了大半天时间解决另一个可能性,就是把我的gsoap大量的产生代码文件另外编译成一个静态库并把binary checkin到svn,一方面加快编译速度,另一方面看看能否解决debug100%cpu占用问题。这个工作基本就是修改makefile的工作,不 过调试起来还是花了一点点时间,因为合成两个静态库在linux下是不像windows那么直接,你要把静态库extract成原先的.o来ar生成新的 静态库,这里面有一定的风险就是同名文件的覆盖,之前我曾经为了避免这个使用了一个ar的开关是-T但是这个是新版编译器才支持的开关,老版的ar,忘了 是什么版本,其实也是挺新的不支持。所以,有些罗嗦。每天干了多少事情真是说不完,因为很多时候就是一层窗户纸,一捅就破,但是之前就是看不清楚。

七月二十四日 当前只有等待等待

有件事情我始终忘记提了,很重要。曾经一段时间我的工作的rhel6.3出现莫名其妙的coredump,同样的程序甚至curl下载文件都会,而在别的 机器正常,猜想原因可能是我自己编译安装的libcurl/libopenssl等等有问题,但是也可能还有不少的软件被我安装过,曾经一度想让管理员重 构一下系统,后来想一想这个是无厘头的普通人的想法,首先不可能是内核的问题,我没有程序我自己也没有触碰,那么仅仅是目前安装的库的问题,这个当然可以 重新安装,于是找来rhel6.3的光盘iso,linux映射光盘mount -o iso9660,然后安装rpm,for i in rpm/*.rpm; do rpm -i $i; done想想看这个是不是就是重新安装了,当然也许有多一些rpm我并不在乎。另一个问题是我曾经需要系统的一些rpm里的静态库,默认安装只给你动态 库,所以只能自己编译,rhel给你的是source rpm,这个需要这样子mkdir build && cd build && rpm2cpio ../curl.src.rpm | cpio -idv然后发现有相当多的patch,一个一个打包累死你,所以,for i in *.patch; do cat $i | patch -p1; done 然后就是configure/make了,不过对于多个编译curl我还是很烦因为他需要libidn,libssh2等等,我每个都下载编译源码,但是 不安装设置configure似乎都不成功。总之很麻烦。
又加班,改bug,回到家好累啊,心跳不齐好几天没法跑步了,埃。花了一天时间搞明白了一件小事,之前以为gdb是python的壳子发现不对,我以前记 得很清楚是的,不知道怎么回事,也许我记错了?是gcc是一个壳子?我去下载rhel的src rpm,发现其实编译rpm很简单,使用rpmbuild --reinstall src.rpm,否则我自己加载patch是不对的因为有的patch是有依存关系,我不知道顺序结果有些就加不上去了,比如有一个patch创建文件, 其后修改这两个的顺序是不能错的。rpmbuild把他们编译在一个固定的地方,比如/root/SOURCE/。。。所以你可以使用rpm -i /root/SOURCE/。。。同时发现那个cpu疯狂的问题其实很可能是我自己的eclipse的问题,就是说也许是设置或者indexer发疯了。 需要把.metadata之类的都删除。我在debug的过程遇到另一个问题,我的代码文件里有写是一模一样的文件名,这个时候eclipse就加载错误 了,解决的办法是把debug/source里的default删除,当然这样第一次它要问你来指向文集。

七月二十五日 当前只有等待等待

怎样在eclipse里面debug一些需要root权限的程序呢?这里说的很清楚我却做不对:我鬼使神差的总是觉得要设置eclipse或者是被debug的程序本身作为可以sudo不需要password的,这个是不是很好笑呢?你不运行sudo那么设置这个sudo visudo里
nick ALL=(root) NOPASSWD:/usr/bin/gdb也没有用,当然你要eclipse里把gdb改为sudo -u nick gdb。
学习ext2编程接口。

八月三日 当前只有等待等待

一直被困扰的是之前以上认为sudo可以工作来debug,但是不知道为什么突然又不行了。编译e2fsprog发生了一些错误,想起来我的笔记本安装的 是gcc4.8版本,改用4.6版。然后链接ext2fs发生com_err的链接错误发现原来e2fs_prog把libcom_err.a编成了一个 单独的库,当然会出现这个问题了。今天终于受到了tpm芯片,插在了主板的20针插槽上,按照这个步骤sudo tpm_takeownership发生错误,需要慢慢的debug了。

八月九日 当前只有等待等待

昨天这个bug是非常有教育意义的,这个是一个经典的问题,对于这个...符号不一定所有的程序员都非常的熟悉,至于说他的handle的宏 va_list的特性就更加不一定了。问题是结合了另一个不是很常用的函数vsnprintf,这个是snprintf的堂兄,不同的是因为它的参数是那 个va_list这个理论的长度是无限的没有人可以保证你分配的内存足够长,与是vsnprintf保证你返回需要的长度让你来分配,但是是否真的返回值 就是需要的长度呢?这里有经典的解释:假定你传入的buffer长度值为n,返回值可能如下:
1. -1; 2. n; 3. n-1; 4. m where m > n;对于情况1,2来说需要的长度是未知的,唯一的办法就是继续加大你的buffer并传入一个相应的更大的n然后看结果如何,甚至结果3是告诉你了 buf可以,但是据说仅仅是骗你的,因为被truncate了仅仅满足了你和函数的合约:我不超出你的buffer的限制n,第四个情况是最好的,我觉得 实现这个结果的程序员是一个勤奋的程序员把用户当作猴子一样看待的好人,从系统的角度来看肯定是不合算的,甚至困难的,也许只有现在的悠哉悠哉的编程员才 有闲情逸致实现它,(BTW,rhel6.3 x86_64是这样子的,真是好人啊。)所以,基本上所有的人都要遵循这个例子的 做法写一个无限循环不断的增大buf。ok,背景总算交代完了,电影都演了二十分钟了主角还没有登场呢,这里的参数va_list要被作为传入参数给 vsnprintf,那么对于大多数程序员来说va_list是一个黑匣子,不同的平台有不同的实现,因此他是一个宏,究竟它是否被只读来使用是一个未知 数,在rhel6.3 x86 32bit下它是一个好人实现的,每次传入结果都是一样的,可是在rhel6.3 x86_64 的64bit下这个实现者给你开了一个玩笑,里面大概是一些指针被vsnprintf移动之后不能复原了,结果可想而知,我写了一个小小的测试程序,这里是测试结果。 第二个例子告诉你如果你不每次初始化结果是有些不可预测的。至于解决就有些戏剧化,我们的代码里这个va_list是作为参数传递进来的,所以,我一开始 想要把呼叫函数合并进来,这个改动太大了,后来Vampire还是很聪明的,要用va_copy这个的确解决了问题,不过你要记得每次使用va_copy 都要配合va_end释放那个copy,至此我的一天有了一点点的成果,实际上这个插曲是昨天的一小部分而已,早晨的时候和UK简单电话会议就在 debug刚刚从32bit升级来的64bit的程序,G在东部一直发邮件报告说makefile改造为64位后的结果有问题,至少在log里面都是充满 了错误信息,我跟他解释64位所依赖的动态库从来没有测试过不正常是很可能的,但是他说的不是一回事,原来是这样子的,之前的makefile只能编译 32位代码,但是G痛恨blade server用32bit linux不能充分利用16G物理内存(32位理论内存也只有4G),所以,他安装了32位的库来在64位机编译32位程序,但是自从我把 makefile改造了自动测试机器的架构他就开始编译64位程序了,自然问题就出现了,我告诉他你要测试32位需要手动改,我相信我没有碰32位的代码 仅仅是makefile的改造,应该没有问题。过了一两个小时他又来邮件说我的gsoap部分makefile对于每个Provider里的程序的.o文 件只在make clean里删除其中一个。我跟他说这是我专门设计的因为那几个不删除的是gsoap自动产生的代码,我只在svn co的第一次的时候编译后来的make clean都不删除了方便程序员加快编译,除非wsdl升级我才重新编译。可以想象他的64位程序和一些之前32位编译的.o链接的问题了吧,他是AIX 的专家,IBM的编译器很不一样,比如ar -x libmy.a分解为.o然后再ar -cr libmy.a *.o和我合并多个静态库的办法,因为新版的ar里的-T的开关在老的rhel5.7上不支持,可是AIX比较神奇可以incremental的把.o加 到现成的.a里,当然事后想一下真的没什么了不起的,因为ar本来就干的工作很少,几乎和concatenate差不了多少,我曾经把我的另一个.a活生 生的加到我的.a里去,链接出错后最后objdump/nm才发现那个失踪的.a静静地躺在另一个.a的肚子里睡觉呢。
中午连吃饭都来不及又要去面试一个在嵌入式干的人的应聘,我是觉得他还不错,mergesort也差不多能写出来,在我的帮助下,但是其他人都认为他 oop很弱,我也就从重了,因为我对于他用windows开发嵌入式程序还是很意外的。反正不管我的事情,宁可招聘强的不要找弱的因为最后工作都会压倒你 身上,这个是硅谷的工作规律,所以,其实是良性的。终于debug我的64位程序在吃饭后有了结果,我真有趣把NULL指针传给cout打印,可是 rhel对我太好了不crash但是所有的stdout都没有了反而害了我。你要是真的爱我,就直接crash不要和我磨机磨机折磨我!随后file replication的NDMP设置出错就是rhel 32和64的区别了吧,之前在gsoap产生的代码里那个我认为没有用的参数我没有初始化32位程序没有抱怨,64位就报错了。直到下班前我把所有的改动 都svn commit才shoot一个email跟UK说遇到32/64兼容问题刚解决星期一再给他们win32/64/rhel/32/64的版本。这里svn 的移动最好是用svn mv之类的我直接拷贝或者mv连带每个文件夹里的.svn都带过去就乱了,之后只能find . -name ".svn" -exec rm -fr {} \;删除所有,然后在svn rm myfolder &&  svn commit -m "delete" && svn add myfoldernewpath非常罗嗦。晚上回到家非常的累,连前天看的电影的名字都忘了,那个是guardian of galaxy很搞笑的片子。虽然不是每天都是如此的惊心动魄,但也差不多了,所以,如果我在红绿灯前睡着这个是有一半原因的。

八月十四日 当前只有等待等待

stackoverflow上的大牛帖,赶快记录下来实践一下,我忍不住破坏自己的原则:直接摘抄了,害怕以后找不到。

Each process has three capability sets:

Each file has the same capability sets. When a new binary is exec()'d, the capabilities of the process change according to the following rules, where:

(simplified from http://www.friedhoff.org/posixfilecaps.html)

In most scenarios, pE' is the only result we care about. Programs that are linked against libcap can call setcap() to change their Effective caps (as long as the caps they try to request are in the Permitted set), but the vast majority of programs don't explicitly touch their caps so we have to arrange for the cap to be effective post-exec().

Having a concrete example will help understanding here... I got fed up with having to 'su' to run openvpn, so I wanted to grant myself the CAP_NET_ADMIN capability to allow the setting of routes and such.

Looking at the last rule (pE' = fE & pP') it's clear that to have CAP_NET_ADMIN in the process's Effective set, CAP_NET_ADMIN must be in the file's Effective set. So, the capabilities system doesn't allow us to simply say "grant CAP_NET_ADMIN to user sqweek" - the program's capabilities are always important.

Being in the file's Effective set isn't enough though, the cap also needs to be in the process's new Permitted set. Lets look at that rule: pP' = fP | (pI & fI). So there's two ways we can get the cap in pP', either we add CAP_NET_ADMIN to the file's Permitted set, or we add it to the file's Inheritable set and make sure it is in the process's Inheritable set.


八月十五日 当前只有等待等待

这里才是源头, 其中的bounding capset如果不看这里就不明白所以。修改/etc/security/capability.conf可以给你的进程增加Inheritable的 capability,但是格式让我困惑了一会儿,你必须把所有的cap用逗号隔开写成一行,否则不认,而且只要有一个错误就前功尽弃,并且系统只读一 次。然后我就ctrl+shift+F6去另一个console去login/logout来看是否登录后权限如此,因为这个游戏是很危险的,很可能把你 自己锁住。对于文件的权限,可以使用setcap/getcap来操作,其中的格式可以参考cap_from_text的manpage的例子来看。至于 说cap的名字只能从代码里面来了。这个给出的具体的例子怎样不使用setuid给ping而只让某些用户能够使用ping非常的好。事实上很多人都不知道居然一个简单的Ping居然有特殊的权限才能运行,这里的很多人指的就是我。
可是两篇文章的公式不一样,这里说的是
pI_new = pI
pP_new = (X & fP) | (fI & pI)
pE_new = pP_new
pE_new = empty
if fE == true
if fE == false
第一眼看过去两个公式不一样,tnnd我的脑子有进水居然相差了,意思就是说fE有最后的生杀予夺的决定权。来验证一下?
总之,作为文件permitable一定不能有,因为结果就退化为setuid了什么人都可以有了,而effective一定不能没有,否则还是没有,文 件的inheritable应该要有,因为要配合用户的inheritable,因为配置/etc/security/capability.conf只 能给用户Inheritable,此外,我曾经想用setcap给文件设定effective似乎不成功,effective是一个特例一定要配合其他才 行,而另外的两个则没有这种限制。
对于nfs和cifs昨天是一个折磨,原本这个是客户端的问题,基本上是用户操作和系统配置和HNAS设置压根不管我的事情,可是我因为要测试不得不自己 做,在linux上一切都是浮云,而在windows上非常的复杂,如果牵涉到安全机制更加的复杂,这里是基本的语法,我一直有误:
1.查看export or share
cifs的share: net view \\172.17.37.46

nfs的export: showmount 172.17.37.46
2.mount到本地磁盘:
cifs的share: net use x:  \\172.17.37.46\cifs-share
nfs的export: mount 172.17.37.46:/nfs-exprt y:\
注意这里的一个小小的trick是如果权限被禁止,nfs只能使用anonymous用户的话,你一定要使用该用户来mount否则无法访问: mount -o anon 172.17.37.46:/nfs-export  m:\
在windows上nfs并不是自动就有的,需要add role去添加那个服务包,然后启动nfs的服务才行,所以,这个是很罗嗦的。


八月十七日 当前只有等待等待

想看看gdb的代码 因为似乎gdb无视文件的权限capabilities,这个据说是安全的考量。可是编译gdb7.1遇到很多的variable set not used的错误,当然是因为-Werror把warning转error了,这个是因为我现在使用的是gcc4.6,这里说的很明确的。问题是我怎么修改makefile呢?不应该的, 是这样子的。我最后是这样子的:./configure CFLAGS='-g -O0 -Wno-unused-but-set-variable' CXXFLAGS='-g -O0 -Wno-unused-but-set-variable'因为要保留原来的-g,不过我把-O2换成了-O0禁止优化,为什么有些无法解释,纯属无厘 头的。
后来我想给java加上权限,它拒绝了,权限给他了,然后他很正义的拒绝启动,真是好同志,不贪不腐,共产党员能做到像这种遇到权力就让该多好。
每天都学习一些新东西,Linux博大精深没有十几年经验算不上精通,我现在连入门都觉得夸张,比如chattr -V +i 对于文件可以添加一个只有lsattr才能看到的attribute,这个immutable可以很让人摸不着头脑因为你不是root你删不掉,其他的+ a也会有用的如果作为log文件的话,这个就是cap_linux_immutable的权限。
找了半天才找到,如果你想知道你的权限,很简单的:capsh --print就看到了bounding set cap:
Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setfcap+i
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,
cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,
cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,34,35
我觉得我的Ubuntu版本内核没有屏蔽任何的cap。只不过/proc/../bound-cap没有了,我也忘了具体路径了因为找不到。
我在gdb/eclipse里debug时候检查了被gdb调起来的我的程序权限和我自己没有区别,我也查看了gdb的源码在一个child- fork.c(名字大概如此)里你可以看到gdb怎么传参数的,这里还解释我之前的一些疑惑,在eclipse里传命令行参数常有单引号双引号的问题,本 来我一直以为这个是eclipse的自己的shell在处理字串的问题,现在看到gdb的源码里缅是先去地用一个当前的shell来把参数传给它,据说这 个是偷懒因为也许*之类的代表所有参数可以自然传递,但是我现在也明白了gdb依赖于shell来运行被debug的,总之很多疑惑,这个是题外话。那么 准备增加cap_sys_ptrace到我的/etc/security/capabilities.conf然后重新login实验一下。又失败了,我 已经把所有的权限都给我自己,也把gdb和我debug的程序都加上了所有的cap,结果依然不行,看来gdb一定走的是另一条路线,是mi?

我差不多被彻底打败了,完全无头绪,权限实在是一个谜题。我把setcap设定了cap_setfcap的+iep,然后我运行setcap再也不需要sudo了,当然我自己本身也有cap_setfcap的Inheritable。


八月十八日 当前只有等待等待

昨天我承认我被彻底打败了,我以为gdb有什么玄虚可以无视可执行程序的权限,而我对于所谓的神秘的mi(machine interface)一无所知,似乎这个是一个多么神秘的问题,在睡梦中冥冥之中提醒了我一个错误的方向,因为梦里总是告诉我有一个权限没有从继承中得 到,从这里就可以知道古人对于梦的迷信是多么的可笑,大多数时候都是线路短路的胡思乱想,怎可当真?于是从梦中醒来我决定开始一个危险的游戏,用gdb来 debug gdb,多么的玄虚?在计算机的哪门基础课里明确说明了什么是computable和什么是uncomputable的,其中用一个程序去运行监视自己应 该是不可计算的吧?(我也忘了,当初也没有搞懂过。)总之gdb不过是一个普通的程序,我昨天编译了现在用来debug有什么不可以?不过的确有些不同就 是似乎它不再理会我的传入参数执意要进入命令行模式,反正无所谓,我抱着必死的决心闯入这飞人的境地来探索未知的领域。里面无数的线程我压根没搞懂,昨天 看的fork-child.c是我的唯一入口,然后柳暗花明我看到了其中的关窍,昨天我已经知道了gdb偷懒不自己用fork/exec直接创建被 debug的程序,也许环境变量需要模拟用户运行,最大限度贴近用户环境?我昨天也小人度君子之腹认为参数处理麻烦,试想写gdb的人会对这个小玩意说 难?我也太不自量里了,可耻。所以,我跟踪了半天只明白了这一件事,而这一件事就解决了我的疑问:谁是你debug的程序的父亲?我以为是gdb,其实不 是他是一个伪装,真正的是shell,完全命令行如这样:/bin/bash exec /home/nick/MyProjects/ext2fs-client/Debug/ext2fs-client看到这里白痴也明白我为什么错了,我 barking the wrong tree。所以当我setcap cap_dac_overide+ie /bin/bash之后我就可以顺利的在eclipse里面debug我的ext2fs-prog来打开/dev/sda1了。
全部攻略如下:
1.编辑/etc/security/capability.conf增加cap_dac_override nick       你不需要其他的权限,需要logout,最好你先用其他tty登录测试一下。
2.把你现在要debug的程序的权限提高setcap cap_dac_override+ie /home/nick/MyProjects/ext2fs-client/Debug/ext2fs-client
3.把你的shell的权限提高:setcap cap_dac_override+ie /bin/bash
4.把你的gdb的权限提高:setcap cap_dac_override+ie `which gdb`      (你还是要提高gdb因为它不是父亲,可是它是祖父。)
至于eclipse完全不需理会他只是看客不需要权限。
这里是本人在stackoverflow.com上发的第一个帖子!感到无比自豪。

八月二十三日 当前只有等待等待

我从gui登录的capsh显示是空的,是否我要加上一下部分在/etc/pam.d/su
需要重启才知道的:
auth required pam_cap.so debug
auth include system-auth
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session optional pam_xauth.so
需要重启才知道的:logout依然不能最后确认,需要真的重启才知道。
这里收藏一下vfs,很有用的。
完整的攻略是这样子的,首先,我自己的权限设定成这样子:

在/etc/security/capability.conf里
cap_dac_override,cap_setfcap,cap_kill    nick

也就是说我自己拥有无视文件拥有者的特权,额外的cap_setfcap的原因是我想在eclipse的build step里的post-build step设定如下: setcap cap_dac_override+ie ${ProjName}之所以我能够不需sudo又不舍定免除sudo password的原因是我把setcap本身的特权提升了,
nick@nick-server64:~$ getcap `which setcap`
/sbin/setcap = cap_setfcap+ei
也就是说我自己的特权配合setcap的cap_setfcap的特权可以自由的给要debug的对象executable设定 cap_dac_override+ie的特权,这样子在我debug的时候就可以自由的打开/dev/sda1之类的原本只有root权限的文件了。
怎么样设定的有些曲折吧?
在e2fs-progs的函数里,ext2fs_get_next_inode如果得到的ext2_ino_t的值为0说明已经把当前的inode穷尽 了,该退出了,函数是始终都返回正常的0的,这是一个小细节。由此,你可以在使用ext2fs_check_directory配合 ext2fs_get_pathname来遍历文件系统的所有的目录,估计一些删除的文件/目录也可以由此有限的恢复一部分。来尝试一下?


八月二十八日 当前只有等待等待

这个基本是众人皆知的小常识,你在一个open source project想要debug,那么编译的configure要去除优化,通常configure选项没有这个直接的,你需要export CFLAGS=‘-g -O0' && ./configure
debug中发现我的文件系统中的dirent的长度似乎是当初用signed int16写入的,而头文件里这个类型是unsigned,难道代码有什么问题?开始怀疑eclipse的gui里面debug也许显示有问题,就直接用 gdb跟踪发现是一样的,那么为什么防范行的代码没有报错呢?比如e2fs-progs里面都会检查dirent的name_len是否超出了 rec_len,这里发现也许是有问题吧,取得name_len的函数做了一个entry->name_len & 0xff这里也许对吧,因为所有的文件名长度都是小于256的,因此这个值其实没有人care?也许是为了其他文件系统扩展用的buffer的长度?
有时候感觉自己就是武侠小说里的武林人士为将来扬名立万而隐居深山修习不知名的武功,手捧一本不知哪里得来的武功秘籍参习修炼,其间岁月如梭,时光似电, 斗转星移,沧海桑田,终于有一日破关出世发现世间已然改变了。当然这个过程里获得的乐趣早已把原先的一心一意要争强好胜扬名立万的念头抛到九霄云外了。这 就是学习。

八月三十日 当前只有等待等待

凤凰卫视在播放末代王朝李鸿章的洋务运动,当时的“1896思变”与当今共产暴政有诸多相似之处,列强环视北洋派大肆采购西欧军火,号称亚洲第一的北洋舰 队究竟不敌日本联合舰队,今天解放军海军号称也有亚洲第一的架势,军费可能是日本的两倍以上,但是究竟是否会重蹈甲午的覆败呢?战争的胜败因素有千万种, 故兵家有言慎战。

十月二十三日 当前只有等待等待

生命中的空白。
打印机坏了,买了新的hp deskjet 2540,安装Ubuntu10.04驱动无法识别wifi下的打印机,折腾了很久很久才偶然发现打印机上的一个按钮,原来要按钮开启wifi- direct的模式,晕倒。同时,打印机支持web gui设置,有众多的工具可以使用,比如hp-setup添加打印机,hp-check检查软件环境等。

十月二十九日 当前只有等待等待

昨天,K提出了一个高深的问题,应该说他发现了我们长久以来的一个很难发现的问题,就是日本方面提供的动态库,比如lib1.so,里是直接静态链接了 stdc++的静态库。本来这个也没有什么不对,这样避免了在不同环境下假如用户不是开发环境没有安装libstdc++.so的问题。但是需要注意的 是,当我们自己的动态库与其链接的时候,如果把这个lib1.so放在了Linking的顺序的前面,比如你又没有把真正需要的libstdc++. so.6放在他的前面,你会链接到libstdc++里较旧的版本,因为日本的库的开发是好多年前了。这样就导致了一些兼容的问题,结果coredump 就这么发生了。
自己做了一个小实验,你的最最简单的helloworld程序甚至空的main也有一下的链接:这里需要提到的是我的编译指令没有提到过libstdc+ +.so,可是编译器都会作此链接,这才是要命的,因为,连接器如果先找到了stdc++库里的函数就直接解决了,而用户的- L/library/search/path是优先寻找的。
nick@nick-server64:~/MyProjects/myLibTest/Debug$ ldd ./mytest.exe
    linux-vdso.so.1 =>  (0x00007fff3d1e0000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f42db4f8000)
    libm.so.6 => /lib/libm.so.6 (0x00007f42db270000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f42db058000)
    libc.so.6 => /lib/libc.so.6 (0x00007f42dacd0000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f42db838000)


十一月十三日 当前只有等待等待

这个问题我理解错了,编译器有所谓的RVO(return value optimization)核心是这样子的:一个函数返回一个临时变量,那么编译器不再作对象的拷贝,(也就是copy constructor)之类的没有被调用了,返回变量的地址被直接用在了栈里面临时变量的地址。这样子可以避免了栈里面的临时变量的解析器,而我们的 core dump都是在exception的unwinding_resume出的问题。解决double exception的ad hoc的方法居然是这样子的:

ExceptionClass ex;
Throw ex;
改变为throw ExceptionClass();据说这个临时变量不在栈里面。
D试图静态链接libstdc++.a但是总是不成功,我查看了readelf -a libstdc++.a | grep __cxa_throw发现很多都是UND,我的理论是.a实际是.o的concatenation并不去作链接,那么静态库里的所有的obj文件都不会 作resolve,因此链接不成。于是我的建议是要拿libstdc++.a的代码来编译,要么就是ar -x把静态库的obj都extract出来作链接。V曾经说linker的-W,static的指令不起作用除非所有的都是静态库才行。


十一月十六日 当前只有等待等待

A Bug's Life。
很久很久以前,一个bug像幽灵一样存在着,他的出现发生在一个异常exception的产生,在客栈(stack)里的过客消亡的瞬间,某些物件 object不愿心甘情愿的被销毁,在通往黄泉路上(destructor)里蓬发出了另一个异常,于是两个叠加的异常让编译器无所侍从,大概是在 unwind_resume之类的函数里直接抛出了信号signal继而就是核爆coredump,面对这一切在我们这些外人看来只看到最后的 coredump和第一个异常的抛出,很难扑捉到第二个异常的起因,很多时候迷信的说法甚嚣尘上:也许是内存地址的越界写(memory corruption),也许是非法指针(dangling pointer),解决的方法也是迷信的无厘头,有人改变编译器的优化模式,有人重新组织代码,还有人干脆把客栈里的访客通通作动态内存分配,在异常抛出 前消灭所有的动态物件保证栈里空空荡荡。但是究竟真正的原因在哪里呢?而且为什么同样的代码只发生在红帽子(rhel6.3 32位)里呢?有人开始怀疑是编译器的问题。。。
终于有一天一个勇士注意到在coredump的backtrace里的蛛丝马迹,系统的__cxa_throw出现在coredump的最后一刻,而这样 的函数本应该来自于libstdc++.so可是为什么它显示自己的出身是一个普通的动态库呢?答案很快有了,当初日本人在开发这个动态库的时候使用了静 态链接把libstd++的代码链接进来,于是我在链接的时候就被日本的动态库“拦截”了,这个和黑客的拦截技术如出一辙,只不过是非恶意的无意之作。
终于找到了问题的症结,如何解决呢?
To link or not to link? This is a question。
有人说使用动态库并坚持下去是唯一不变的选择。于是调整linker的链接顺序把-lstdc++放在前面,可是,以前就是这样为什么不成功呢?有一个观 察是即使你不写-lstdc++的话编译器也会在最后去主动链接它,所以,我的猜想编译器只有最后才去链接。另一个猜想是你虽然把-lstdc++放在了 前面,可是我们把-L/japan/library/path也放在了前面,因为默认的系统的路径是没有用户自己的-L的search path来的优先的,因此,linker在搜索的时候会优先找到日本的动态库。
我觉得静态链接是唯一的解决办法,因为可靠。学编程号称很多年的你,究竟理解这些有几成

在g++/gcc的参数里-W,后面是给linker的参数,你告诉linker我要静态static不就完了? end of story. period. 真的吗?我告诉你不行,你先告诉我rhel的gcc的版本是什么,什么4.4.7那么不行,因为-W,static后面只能都是.a才行,如果你混合了. so的话,编译器又无所适从,就退化回动态库了。那么你就-Bstatic lib1.a lib2.a -Bdynamic lib3.so lib4.so不就行了?还有人说何必那么麻烦,你升级gcc到4.7就可以了。后一种做法很有趣,我们升级了编译器,(在操作系统里如何运行两个版本的 gcc呢?安装的时候有一个小工具可以改变symlink之类的还包括环境变量等等。)然后单单运行-W,static果然就做了静态链接,有趣的是编译 器也不过就是自己生成了-Bstatic ... -Bdyanmic原理和自己手动一样的,那么升级编译器是否升级了glibc之类的类库呢?(问这个问题肯定是重要的,因为发行环境变了你要求你的用户 也要升级编译环境就是大问题了。)gcc --print-search-dirs发现并没有指向不同的libc的版本,我相信升级编译器不可能需要升级glibc否则你要把linux的文件系统 (所有的binary,不是“file system”)所以,这个地方要纠正我的一个错误观念,我原来认为编译gcc一定要升级glibc,其实,这个是无厘头,你要升级的是编译器,自然要用 当前的glibc来编译gcc4.7,只不过这个有时候确实比较困难而已。
如果你还不确定升级编译器是否真的改变了glibc,不妨看看是否有升级版的libstdc++.so版本,至少我们没有看到libstdc++.a的别的版本。
故事真的结束了吗?升级了编译器静态编译依然没有解决动态库被拦截的问题,难道-W,static真的没有用?我用readefl -a libstdc++.a | grep __cxa_throw发现有很多的UND,为什么? 用objdump -t或者nm -u,怎么解释?我以为静态库都是obj的concatenation,一个函数在多个代码文件里反复出现是正常的,只在一个obj里有实现而已,那么静 态链接是不需要解决resolve的,所以留下了无数的空洞(UND=undefined)那么我们即便是链接静态库也不能这么作。其实,这是一个 programming 101的问题,究竟做什么才能做到静态链接呢?这个问题有那么难?问这个问题的人只有像我这样对编译原理似懂非懂的人,链接的过程就是寻找解决 (resolve)的过程,这都是发生在本地找不到的情况,在我看来静态库根本就不能作为链接的搜寻的对象,因为你根本不能动态加载,你只能把它的代码 (二进制码)作为本地的一部分进行本地的链接,所以,很正常的是把里面的obj都揭开来: ar -x libstdc++.a。 所以,最后就是要解开成一个obj来作链接,这个问题不是我天天都遇到的吗?每次都忘记。


十一月十八日 当前只有等待等待

把以前的工具重新拾起来,因为现在上传到amazon S3不再是爱好而是必须的。

十一月二十二日 当前只有等待等待

以前的工具小改一下,因为不想用boost,我的ubuntu安装的boost版本 变了,原本就是一个目录遍历完全没有必要使用boost,同时以前是那个webhosting的变态安全机制不允许我使用中文名字在url里转译,我后来 完全按照他们的要求把Url里的中文转换成安全字符,可是我的webhosting的文件名他们并不转译回去,所以文件名含中文的都不能访问。现在 amazon没有这个限制了。
昨天K因为健康原因离职很可惜,人的健康真的是一个人最大的财富。关于libgcc才是昨天知道的,这个gcc的编译是很庞大复杂的,足见的编译器不是任 何大公司可以轻而易举掌控的了的,需要成百的优秀的人的努力。我想重做一遍D的过程,就是把stdc++中的exception handling部分编译到当前项目中去,我去问他的一些细节的时候,看得出他有明显的抵触情绪,我只能跟他说这和工作无关纯属个人兴趣。求人不如求己, 我压根就没有什么额外的意思。
从垃圾堆里找到了2009年做手机的小工具,是一个水波纹的实现,从哪里抄来的。
g++ -nodefaultlibs -nostdlib -shared -fPIC -static-libgcc -static-libstdc++ ./myShareLib.cpp -o myShareLib.so
寻找到了古老的收藏品,windows的秘密,123,我现在对于这个已经很陌生了。
每次使用这个作amazon S3的同步

十一月二十四日 当前只有等待等待

认真学习ext2文件系统

十一月二十六日 当前只有等待等待

g++ -fPIC -static-libgcc -nostartfiles -nodefaultlibs -nostdlib -fno-exceptions -L. -o test.so  test.cpp --shared
其实并非人人都知道的。编译器的那个所谓的personality是一个空的全局变量,如果你的程序没有用到exception的话,就可以去掉它,这样子编译的动态库就不会再依赖于默认的运行库了。

十二月三日 当前只有等待等待

突然之间我的工作站的ssh的免password的login失效,显示server refused our key。 其实通用的做法是打开debug log: 在/etc/ssh/sshd_config里设定LogLevel DEBUG3然后查看/var/log/secure,然后我发现了我的原因,仅仅是因为我的Home directory的权限扩大了导致sshd拒绝我的登录。

十二月四日 当前只有等待等待

早晨起来给wiki捐了三块钱,顺便修正了一个Paypal的恼人的地方,就是我已经关闭了它的信用卡,可是他还是我的首选付款方式。
天天加班而不得。
十二月十四日是一个重要的日子。(后来想起来的。22街)

十二月十八日 当前只有等待等待

事情是这样子的,在K的CentOS上命令行自动换行不能正确执行总是出错跳到当前行首字符覆盖很让人头疼,google发现了问题的源头。是PS1的定义有问题,这个是修改前后的区别:

Before correcting $PS1 was:

export PS1='\e[1;32m\u@\h:\w$ \e[m'

after fix:

export PS1='\[\e[1;32m\]\u@\h:\w$ \[\e[m\]'
这里是stackoverflow最早的帖子
这里是另一个小小的提示。在shell里最早的是/etc/environment,随后是/etc/profile,然后如果你使用bash, /etc/bash_profile要被执行,通常大家都会自己定义~/.bashrc,但实际上它是在~/.bash_profile里被 include的,而且是在开头就加载了,意思就是说/etc/bash_profile在呼叫~/.bash_profile的时候, ~/.bashrc首先被定义了,K在~/.bash_profile里定义了一个$PS1导致我在~/.bashrc里的又被覆盖了。

我的主板的hdmi输出有问题,使用双显示器第二个显示器只能接vga,第一个是dvi。


十二月二十四日 当前只有等待等待

说起来惭愧,对于c和c++不兼容的地方还真的不是很清楚。于是对于这个编译的问题就 有一个模糊的认识,在c里struct的初始化default value在c++里是不可以的,这个不是使用-std=c++98就能解决的,这个是不兼容的,要么就把文件名改回.c使用gcc而不是使用g++,要 么就是只能使用constructor的初始化操作符,没有什么简单的解决办法。struct A{int member1;}; static struct A a={.member1=1,};   ====> struct A{int member1; A():member1(1){;}}; 基本上这里就是最好的解决办法了。

up.gif (335 bytes)