scnu-socoding / scnuoj

华南师范大学软件学院在线评测系统
https://oj.socoding.cn
BSD 3-Clause "New" or "Revised" License
43 stars 6 forks source link

judge用户的作用是? #18

Closed fearlessxjdx closed 3 years ago

fearlessxjdx commented 3 years ago

安装指南中提到要创建一个judge用户,但并没有在安装指南其他处看到要如何使用。

我按照安装指南部署好应用后,在web上测试了大部分功能都正常,但是评测功能有问题。。

用 debug 模式运行 dispatcher,看了下日志,好像评测机无法正常获取提交程序的输出。日志如下:

Enable OI mode.
Enable DEBUG mode.
/bin/ln: failed to create symbolic link '/opt/scnuoj/judge/0': File exists
/bin/ln: failed to create symbolic link '/dev/shm/jnoj/opt/scnuoj/judge/data': File exists
mysql
root
root
scnuoj
3306
2
64
-Xms64M
-Xmx128M
1
0
Main=Main.cstatus = 0
init_call_counter:0
pid=1045 [Solution ID: 5] judging /opt/scnuoj/judge/data/1000/0.in
.......
{
    "subtasks": [{
            "cases":    [{
                    "verdict":  6,
                    "time": 1,
                    "memory":   540,
                    "exit_code":    0,
                    "input":    "1 2",
                    "output":   "3",
                    "user_output":  "",
                    "checker_exit_code":    0,
                    "checker_log":  ""
                }, {
......

这两个 fail 似乎就是这样的?我删了文件,第二次执行还是这样的,不知道是不是bug

"user_output": "", 在这个地方,不管我程序怎么输出,user_output 获取到的都是空,不知道问题出在哪里。


我是在docker下搭的,所以大部分进程都是root运行的

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 20:58 pts/0    00:00:00 /bin/bash
root        18     0  0 20:59 pts/1    00:00:00 bash
root        38     1  0 21:02 ?        00:00:00 WorkerMan: master process  start_file=/opt/scnuoj/socket.php
root        39    38  0 21:02 ?        00:00:00 WorkerMan: worker process  PHPSocketIO socketIO://0.0.0.0:2120
root       774    18  0 21:09 pts/1    00:00:00 ./dispatcher -d -o
root      1130     1  0 21:15 ?        00:00:00 nginx: master process /usr/sbin/nginx
www-data  1131  1130  0 21:15 ?        00:00:00 nginx: worker process
www-data  1195  1130  0 21:15 ?        00:00:00 nginx: worker process
root      1214     1  0 21:15 ?        00:00:00 php-fpm: master process (/etc/php/7.4/fpm/php-fpm.conf)
www-data  1215  1214  0 21:15 ?        00:00:00 php-fpm: pool www
www-data  1216  1214  0 21:15 ?        00:00:00 php-fpm: pool www
root      1218    18  0 21:15 pts/1    00:00:00 ps -ef

没有看到 judge 用户在做什么事情,所以想问下这个 judge 用户有什么用,我在docker下需要做什么调整吗?暂时没想到其他原因。。求教

bobby285271 commented 3 years ago

没想到有除了 SCNU 的人用... 我找个时间在 Docker 试一下看看能不能重现,可能没那么快有结论(捂脸)。我曾经遇到过一模一样的报错,原因是忘记在题目设置里指定是否开启 SPJ(Polygon 的默认设置还没补上,就出大问题),不过 1000 题好像是 migration 导入的出的问题我得看看...

// 内心:啊啊啊啊啊啊还有一堆 bug 没改啊完了完了...


judge 用户理论上是必须的,你直接在 judge/src/judge.c 下搜 judge 还有 1536,是可以看到写死了要这个用户的。

// 根据安装指南,创建 judge 用户时是指定了用户 ID 号的。

来几个例子:

https://github.com/SCNU-SoCoding/scnuoj/blob/6583e481f6dc9ecaf46d4c0492b6b8af54d61d57/judge/src/judge.c#L423

https://github.com/SCNU-SoCoding/scnuoj/blob/6583e481f6dc9ecaf46d4c0492b6b8af54d61d57/judge/src/judge.c#L704-L709

/* Set the user ID of the calling process to UID.
   If the calling process is the super-user, set the real
   and effective user IDs, and the saved set-user-ID to UID;
   if not, the effective user ID is set to UID.  */
extern int setuid (__uid_t __uid) __THROW __wur;

在服务器上试了一下这个用户也是有干活的:

$ ps -fu judge
UID          PID    PPID  C STIME TTY          TIME CMD
judge    2930630 2929568 99 22:59 ?        00:00:02 ./Main

至于为什么这么设计,毕竟判题机代码是从 HUSTOJ 到 JNOJ 再到 SCNUOJ 一路传下来的不好说,就是限制访问权限吧...

fearlessxjdx commented 3 years ago

@bobby285271 感谢回复,我想问几个问题。

  1. 您的 scnuoj 目录的所有者是谁(我目前是root)?
  2. 有哪些目录 judge 用户需要有写权限?
  3. 您的 ./dispatcher./polygon 是用 judge 用户运行的吗?
bobby285271 commented 3 years ago
  1. 您的 scnuoj 目录的所有者是谁(我目前是root)?
$ ls -l
drwxrwxr-x 26 scnuoj scnuoj   4096 2月  26 19:01 scnuoj

如果 webapp 工作正常的话,应该不用再去碰这个的。

  1. 有哪些目录 judge 用户需要有写权限?

部署的时候是不需要把任何文件或目录所有者设置为 judge 的。

  1. 您的 ./dispatcher./polygon 是用 judge 用户运行的吗?

必须是 root 用户。

fearlessxjdx commented 3 years ago

@bobby285271 我是 Ubuntu18.04+PHP7.4 ,跑在 docker 容器内。目录和文件的 mod 我是按照 git 上的,拉下来没改过。除了 scnuoj 目录我是属于 root 的外,其他我们都一样。一下想不到哪里会有问题了。。

难道是评测服务所在容器需要设置 privileged 或者特别的 cap_drop 属性才能正常吗,不知道该怎么弄了,一个个试有点费时,没辙了。。

我刚试了下,添加 privileged 也不行。那看样子还是 judge 用户上的问题可能性大一点。

bobby285271 commented 3 years ago

TL;DR: 试了一下,判题是没有问题的,你可能需要描述一下你的配置过程我看看有啥问题...


这是我的重现步骤,不知道跟安装指南会不会有什么出入:

懒得配 PPA,拉了个 Ubuntu 20.04 LTS(带 systemd 的)试了一下(宿主机是 NixOS,所有命令均使用 root 执行):

// 之前给 Docker 创建过 network,不过跟这个 issue 应该没有什么关联:

# docker run -d --name systemd-ubuntu --network bobby285271 --ip 192.168.4.5 --tmpfs /tmp --tmpfs /run --tmpfs /run/lock -v /sys/fs/cgroup:/sys/fs/cgroup:ro jrei/systemd-ubuntu
# docker exec -it systemd-ubuntu bash
# apt update
# apt dist-upgrade
# apt install nginx php7.4 php7.4-curl php7.4-xml php7.4-fpm php7.4-mysql git composer mariadb-server libmysqlclient-dev libmysql++-dev nano build-essential
# systemctl enable nginx mariadb php7.4-fpm --now
# cd /var/www/
# git clone https://github.com/SCNU-SoCoding/scnuoj --depth=1
# cd scnuoj/
# composer install
# mysql -uroot
> create database scnuoj;
> grant all privileges on *.* to socoding@localhost identified by 'socoding';
> exit;
# nano /etc/nginx/sites-enabled/default
# systemctl restart nginx
# ./yii install
# useradd -m -u 1536 judge
# cd judge/
# make
# ./dispatcher

/etc/nginx/sites-enabled/default

server {
    listen 80;
    listen [::]:80;

    root /var/www/scnuoj/web;
    client_max_body_size 0;
    index index.php;
    server_name scnuoj;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    }
}

随后使用 ./yii install 创建的帐号登陆,直接前往 1000 题提交代码,正常判题。

fearlessxjdx commented 3 years ago

额,换成 Ubuntu 20.04 后可以了。后来试了几种可能,还是没能在 20.04 上重现之前的问题。

@bobby285271 我还有个疑问,/sys/fs/cgroup:/sys/fs/cgroup:ro 不加的话,对 oj 运行有什么影响吗?我自己没能察觉到影响。

bobby285271 commented 3 years ago

dockerhub 里面是这样写的。大概确实不是必须的,但说实话我对 cgroup 不是很了解...