apache分析之一、svn:Could not open the requested SVN filesystem

一、问题描述
本来是想测试一下svn的post-commit hook为什么能够实现对于后台任务的同步等待,所以就搭建了一个apache和svn的服务器程序,但是在调试的过程中一直出现文件系统打不开的问题,在apache的错误日志中也可以看到下面的提示内容,
 1647 [Sun Oct 14 11:40:41.036210 2012] [:error] [pid 31176:tid 3064986480] (2001        4)Internal error: [client 192.168.203.1:3684] traced call
   1648 [Sun Oct 14 11:40:41.036448 2012] [dav:error] [pid 31176:tid 3064986480] [c        lient 192.168.203.1:3684] Could not fetch resource information.  [500, #0]
   1649 [Sun Oct 14 11:40:41.036468 2012] [dav:error] [pid 31176:tid 3064986480] [c        lient 192.168.203.1:3684] Could not open the requested SVN filesystem  [500        , #13]
   1650 [Sun Oct 14 11:40:41.036482 2012] [dav:error] [pid 31176:tid 3064986480] [c        lient 192.168.203.1:3684] Could not open the requested SVN filesystem  [500        , #13]
   1651 [Sun Oct 14 11:40:41.807462 2012] [dav:error] [pid 31176:tid 3054496624] [c        lient 192.168.203.1:1050] Could not fetch resource information.  [301, #0]
   1652 [Sun Oct 14 11:40:41.807514 2012] [dav:error] [pid 31176:tid 3054496624] (2        )No such file or directory: [client 192.168.203.1:1050] Requests for a coll        ection must have a trailing slash on the URI.  [301, #0]
二、分析过程
由于apache支持调试模式运行,所以在apache启动的过程中,添加-X参数,这样apache就是自己单进程执行,这样便于调试,如果使能了apache的派生模式,我们不会知道是哪个进程执行了这个任务,所以这是一个将问题范围缩小的功能。
在apache的源代码中搜索这个错误提示字符串"Could not open the requested SVN filesystem",可以找到该提示位于httpd-2.4.2modulesdavmainmod_dav.c文件的dav_get_resource函数中,在该函数打断点,在错误提示的上一样单步步入
    /* resolve the resource */
    err = (*conf->provider->repos->get_resource)(r, conf->dir,
                                                 label, use_checked_in,
                                                 res_p);
    if (err != NULL) {
        err = dav_push_error(r->pool, err->status, 0,
                             "Could not fetch resource information.", err);
        return err;
    }
最后找到出错位置
164        if (perm == APR_OS_DEFAULT) {
(gdb) 
165            fd = open(fname, oflags, 0666);
(gdb) bt
#0  apr_file_open (new=0xb61fc02c, fname=0x999bb58 "/home/svnuser", flag=129, 
    perm=4095, pool=0xa660a6c0) at file_io/unix/open.c:165
#1  0x0806b892 in ap_pcfg_openfile (ret_cfg=0xb61fe07c, p=0xa660a6c0, 
    name=0x999bb58 "/home/svnuser") at util.c:860
#2  0x00c418f2 in check_password (r=0xa660a700, user=0xa660c108 "tsecer", 
    password=0xa660c0f7 "tsecer") at mod_authn_file.c:84
#3  0x00145f31 in authenticate_basic_user (r=0xa660a700) at mod_auth_basic.c:241
#4  0x080806c9 in ap_run_check_user_id (r=0xa660a700) at request.c:79
#5  0x0808169b in ap_process_request_internal (r=0xa660a700) at request.c:233
#6  0x080a2c54 in ap_process_async_request (r=0xa660a700) at http_request.c:315
#7  0x0809f3cf in ap_process_http_async_connection (c=0xb6c01c00)
    at http_core.c:143
#8  0x0809f5a2 in ap_process_http_connection (c=0xb6c01c00) at http_core.c:228
#9  0x08095ee3 in ap_run_process_connection (c=0xb6c01c00) at connection.c:41
#10 0x080ab9ef in process_socket (thd=0x99bd290, p=0xb6c019c8, sock=0xb6c01a10, 
    cs=0xb6c01bb8, my_child_num=0, my_thread_num=1) at event.c:917
#11 0x080adb14 in worker_thread (thd=0x99bd290, dummy=0xb6c00468) at event.c:1744
#12 0x009bfe0d in dummy_worker (opaque=0x99bd290) at threadproc/unix/thread.c:142
#13 0x00391925 in start_thread () from /lib/libpthread.so.0
#14 0x002e707e in clone () from /lib/libc.so.6
(gdb) 
这里可以看到对于svn文件通过绝对路径打开,并且要求权限是666权限。我们看一下内核中对于绝对路径打开的限制:__link_path_walk-->>
static int exec_permission_lite(struct inode *inode,
                       struct nameidata *nd)
{
    umode_t    mode = inode->i_mode;

    if (inode->i_op && inode->i_op->permission)
        return -EAGAIN;

    if (current->fsuid == inode->i_uid)
        mode >>= 6;
    else if (in_group_p(inode->i_gid))
        mode >>= 3;

    if (mode & MAY_EXEC)
        goto ok;
如果一个文件夹对该用户没有可执行权限,那么该用户是无法打开该文件夹的任意一个文件的。
三、解决办法
为svn建立一个单独的文件,修改该文件夹的权限为可打开权限。
chmod 777 -R /path/to/svn/repos
其实回头看看之前apache的输出日志,其中已经有显示到13这个错误码,在内核中,该错误码的意义为权限不足:
#define    EACCES        13    /* Permission denied */
只是说不知道该字段的意义而没有关注
原文地址:https://www.cnblogs.com/tsecer/p/10487805.html