分类 电脑 下的文章

用 roudcube webmail 的 password plugin 更改密码后 postfix 报错 SQL prepare failed: disk I/O error

环境:服务端是 postfix + sqlite3 ,当 roundcube webmail 配置了 password 插件后,用户能更改密码,但之后 postfix 报错,错误信息是 SQL prepare failed: disk I/O error 。影响的结果是,收不了邮件。

原因:roundcube 的 sqlite 连接配置时,使用了 PRAGMA journal_mode = WAL ,但 postfix 不支持。

尝试:可将 sqlite 的 journal_mode 更改回原来的 delete 。如在Linux里执行命令: sqlite3 /var/vmail/postfixadmin.db 'PRAGMA journal_mode=delete;'

# sqlite3 /var/vmail/postfixadmin.db
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> PRAGMA journal_mode;
delete

参考:

在 debian 12 安装 postfix + dovecot + sqlite3 + postfixadmin + roundcube

需求:在 debian 12 系统里搭建用 postfix 和 dovecot ,用 sqlite3 存储,postfixadmin 管理,roundcube 作为 webmail 。

步骤:

参考的配置文件内容:

# postconf -n
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
append_dot_mydomain = no
biff = no
compatibility_level = 3.6
inet_interfaces = all
inet_protocols = all
mailbox_size_limit = 0
mydestination = $myhostname, mail.drsvps.2xinxian.top, localhost.drsvps.2xinxian.top, , localhost
myhostname = mail.drsvps.2xinxian.top
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
myorigin = /etc/mailname
readme_directory = no
recipient_delimiter = +
relayhost =
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_security_level = may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_tls_cert_file = /etc/ssl/certs/postfix.pem
smtpd_tls_key_file = /etc/ssl/private/postfix.key
smtpd_tls_security_level = may
virtual_alias_maps = sqlite:/etc/postfix/sqlite_virtual_alias_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_catchall_maps.cf
virtual_mailbox_domains = sqlite:/etc/postfix/sqlite_virtual_domains_maps.cf
virtual_mailbox_maps = sqlite:/etc/postfix/sqlite_virtual_mailbox_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_mailbox_maps.cf
virtual_transport = lmtp:unix:private/dovecot-lmtp
# cat /etc/postfix/sqlite_virtual_alias_maps.cf
dbpath = /var/vmail/postfixadmin.db
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
# cat /etc/postfix/sqlite_virtual_alias_domain_maps.cf
dbpath = /var/vmail/postfixadmin.db
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = printf('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
# cat /etc/postfix/sqlite_virtual_alias_domain_catchall_maps.cf
dbpath = /var/vmail/postfixadmin.db
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = printf('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
# cat /etc/postfix/sqlite_virtual_domains_maps.cf
dbpath = /var/vmail/postfixadmin.db
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
# cat /etc/postfix/sqlite_virtual_mailbox_maps.cf
dbpath = /var/vmail/postfixadmin.db
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
cat /etc/postfix/sqlite_virtual_alias_domain_mailbox_maps.cf
dbpath = /var/vmail/postfixadmin.db
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = printf('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
# postconf -M
smtp       inet  n       -       y       -       -       smtpd
pickup     unix  n       -       y       60      1       pickup
cleanup    unix  n       -       y       -       0       cleanup
qmgr       unix  n       -       n       300     1       qmgr
tlsmgr     unix  -       -       y       1000?   1       tlsmgr
rewrite    unix  -       -       y       -       -       trivial-rewrite
bounce     unix  -       -       y       -       0       bounce
defer      unix  -       -       y       -       0       bounce
trace      unix  -       -       y       -       0       bounce
verify     unix  -       -       y       -       1       verify
flush      unix  n       -       y       1000?   0       flush
proxymap   unix  -       -       n       -       -       proxymap
proxywrite unix  -       -       n       -       1       proxymap
smtp       unix  -       -       y       -       -       smtp
relay      unix  -       -       y       -       -       smtp -o syslog_name=postfix/$service_name
showq      unix  n       -       y       -       -       showq
error      unix  -       -       y       -       -       error
retry      unix  -       -       y       -       -       error
discard    unix  -       -       y       -       -       discard
local      unix  -       n       n       -       -       local
virtual    unix  -       n       n       -       -       virtual
lmtp       unix  -       -       y       -       -       lmtp
anvil      unix  -       -       y       -       1       anvil
scache     unix  -       -       y       -       1       scache
postlog    unix-dgram n  -       n       -       1       postlogd
maildrop   unix  -       n       n       -       -       pipe flags=DRXhu user=vmail argv=/usr/bin/maildrop -d ${recipient}
uucp       unix  -       n       n       -       -       pipe flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
ifmail     unix  -       n       n       -       -       pipe flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient)
bsmtp      unix  -       n       n       -       -       pipe flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient
scalemail-backend unix - n       n       -       2       pipe flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension}
mailman    unix  -       n       n       -       -       pipe flags=FRX user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py ${nexthop} ${user}
submission inet  n       -       n       -       -       smtpd -o syslog_name=postfix/submission -o smtpd_tls_security_level=encrypt -o smtpd_sasl_auth_enable=yes -o smtpd_client_restrictions=permit_sasl_authenticated,reject
# doveconf -n
# 2.3.19.1 (9b53102964): /etc/dovecot/dovecot.conf
# Pigeonhole version 0.5.19 (4eae2f79)
# OS: Linux 6.1.0-9-amd64 x86_64 Debian 12.0 ext4
# Hostname: mail.drsvps.2xinxian.top
auth_mechanisms = plain login
disable_plaintext_auth = no
first_valid_uid = 150
last_valid_uid = 150
mail_gid = mail
mail_location = maildir:/var/vmail/%d/%n
mail_privileged_group = mail
mail_uid = vmail
namespace inbox {
  inbox = yes
  location =
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox Junk {
    special_use = \Junk
  }
  mailbox Sent {
    special_use = \Sent
  }
  mailbox "Sent Messages" {
    special_use = \Sent
  }
  mailbox Trash {
    special_use = \Trash
  }
  prefix =
}
passdb {
  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = sql
}
protocols = " imap lmtp pop3"
service auth {
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
  unix_listener auth-userdb {
    mode = 0600
    user = vmail
  }
}
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = postfix
    mode = 0600
    user = postfix
  }
}
ssl_cert = </etc/ssl/certs/postfix.pem
ssl_client_ca_dir = /etc/ssl/certs
ssl_dh = # hidden, use -P to show it
ssl_key = # hidden, use -P to show it
userdb {
  args = /etc/dovecot/dovecot-sql.conf.ext
  driver = sql
}
# cat /etc/nginx/sites-enabled/postfixadmin
server {
        listen 8082 default_server;
        listen [::]:8082 default_server;

        # SSL configuration
        #
        listen 8083 ssl default_server;
        listen [::]:8083 ssl default_server;

        ssl_certificate     /etc/ssl/certs/postfix.pem;
        ssl_certificate_key /etc/ssl/private/postfix.key;

        root /opt/www/postfixadmin/public;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
               include snippets/fastcgi-php.conf;
               fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}
cat /opt/www/postfixadmin/config.local.php
<?php
$CONF['configured'] = true;
$CONF['database_type'] = 'sqlite';
$CONF['database_name'] = '/var/vmail/postfixadmin.db';

$CONF['aliases'] = '0';
$CONF['mailboxes'] = '0';
$CONF['domain_quota'] = 'NO';
$CONF['password_expiration'] = 'NO';
$CONF['setup_password'] = '$2y$10$n6BEmoey9hBdqRiXt.aI2OR6KwY2SObjH88ibJYX2hcMWfetgWQIe';
# cat /etc/nginx/sites-enabled/mail
server {
        listen 80;
        listen [::]:80;

        # SSL configuration
        #
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;

        ssl_certificate     /etc/ssl/certs/postfix.pem;
        ssl_certificate_key /etc/ssl/private/postfix.key;

        root /opt/www/mail/public_html;

        # Add index.php to the list if you are using PHP
        index index.php index.html index.htm index.nginx-debian.html;

        server_name mail.drsvps.2xinxian.top;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
               include snippets/fastcgi-php.conf;
               fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #       deny all;
        #}
}

参考命令:

    9  hostnamectl set-hostname mail.drsvps.2xinxian.top
   10  vi /etc/hosts
   11  exec bash
   12  apt update
   13  man useradd
   14  man useradd
   15  useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin -c "Virtual Mail User" vmail
   16  ls -l /var/
   17  mkdir -p /var/vmail
   18  chmod -R 770 /var/vmail
   19  chown -R vmail:mail /var/vmail
   20  apt install postfix postfix-sqlite
   21  apt install php-fpm nginx php-imap php-mbstring
   22  ls
   23  ls
   24  more exec_recipe.log 
   25  ls
   26  more recipe_-398.log 
   27  ls
   28  ls
   29  cd /etc/nginx/sites-enabled/
   30  ls
   31  cp default postfixadmin
   32  vi postfixadmin 
   33  systemctl restart nginx
   34  cd /opt/
   35  ls
   36  mkdir www
   37  cd www
   38  ls
   39  wget https://github.com/postfixadmin/postfixadmin/archive/refs/tags/postfixadmin-3.3.13.tar.gz
   40  tar -xzvf postfixadmin-3.3.13.tar.gz 
   41  mv postfixadmin-postfixadmin-3.3.13 postfixadmin
   42  cd postfixadmin
   43  ls
   44  cp -a config.inc.php config.local.php 
   45  vi config.local.php 
   46  vi config.local.php 
   47  vi config.local.php 
   48  cd ..
   49  chown -R www-data:www-data postfixadmin
   50  touch /var/vmail/postfixadmin.db
   51  chown vmail:mail /var/vmail/postfixadmin.db
   52  ls -l /var/vmail/postfixadmin.db 
   53  usermod -a -G mail www-data
   54  chmod 770 /var/vmail/postfixadmin.db 
   55  ls
   56  cd postfixadmin
   57  ls
   58  vi /etc/nginx/sites-enabled/postfixadmin 
   59  systemctl restart nginx
   60  vi config.local.php 
   61  cd ..
   62  ls
   63  ls -l
   64  cd postfixadmin
   65  ls
   66  vi config.local.php 
   67  ls -l /var/vmail/postfixadmin.db
   68  apt install php-sqlite
   69  apt install php-sqlite3
   70  systemctl restart php8.2-fpm
   71  cd public/
   72  ls
   73  cd ..
   74  ls
   75  mkdir templates_c
   76  chown -R www-data:www-data templates_c/
   77  vi /etc/postfix/sqlite_virtual_alias_maps.cf
   78  vi /etc/postfix/sqlite_virtual_alias_domain_maps.cf
   79  vi /etc/postfix/sqlite_virtual_alias_domain_catchall_maps.cf
   80  vi /etc/postfix/sqlite_virtual_domains_maps.cf
   81  vi /etc/postfix/sqlite_virtual_mailbox_maps.cf
   82  vi /etc/postfix/sqlite_virtual_alias_domain_mailbox_maps.cf
   83   
   84  postconf -e "virtual_mailbox_domains = sqlite:/etc/postfix/sqlite_virtual_domains_maps.cf"
   85  postconf -e "virtual_alias_maps =  sqlite:/etc/postfix/sqlite_virtual_alias_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_catchall_maps.cf"
   86  postconf -e "virtual_mailbox_maps = sqlite:/etc/postfix/sqlite_virtual_mailbox_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_mailbox_maps.cf"
   87  postconf -n
   88  postconf -e "smtpd_sasl_type = dovecot"
   89  postconf -e "smtpd_sasl_path = private/auth"
   90  postconf -e "smtpd_sasl_auth_enable = yes"
   91  postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"
   92  postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"
   93  postconf -e "smtpd_tls_cert_file = /etc/ssl/certs/postfix.pem"
   94  postconf -e "smtpd_tls_key_file = /etc/ssl/private/postfix.key"
   95  postconf -n
   96  vi /etc/postfix/master.cf
   97  apt-get install dovecot-imapd dovecot-lmtpd dovecot-pop3d dovecot-sqlite
   98  vi /etc/dovecot/conf.d/10-mail.conf
   99  vi /etc/dovecot/conf.d/10-auth.conf
  100  vi /etc/dovecot/conf.d/auth-sql.conf.ext 
  101  vi /etc/dovecot/dovecot-sql.conf.ext
  102  vi /etc/dovecot/dovecot-sql.conf.ext
  103  vi /etc/dovecot/conf.d/10-ssl.conf
  104  vi /etc/dovecot/conf.d/10-master.conf
  105  systemctl restart dovecot
  106  journalctl -u dovecot
  107  journalctl -u dovecot -n 20
  108  journalctl -u dovecot -n 20 --no-pager
  109  wget -O -  https://get.acme.sh | sh -s email=my@example.com
  110  /root/.acme.sh/acme.sh --issue -d mail.drsvps.2xinxian.top --webroot /var/www/html 
  111  ln -s /root/.acme.sh/mail.drsvps.2xinxian.top_ecc/fullchain.cer /etc/ssl/certs/postfix.pem
  112  ln -s /root/.acme.sh/mail.drsvps.2xinxian.top_ecc/mail.drsvps.2xinxian.top.key /etc/ssl/private/postfix.key
  113  systemctl restart dovecot
  114  ss -anp | grep :110
  115  cd ..
  116  ls
  117  wget https://github.com/roundcube/roundcubemail/releases/download/1.6.9/roundcubemail-1.6.9-complete.tar.gz
  118  tar -xzvf roundcubemail-1.6.9-complete.tar.gz 
  119  mv roundcubemail-1.6.9 mail
  120  chown -R www-data:www-data mail
  121  ls
  122  cd ..
  123  ls
  124  cd www
  125  ls
  126  touch round.db
  127  chown www-data:www-data round.db
  128  ls
  129  mv mail /var/www/html/
  130  mv round.db /var/www
  131  vi /etc/nginx/sites-enabled/default 
  132  systemtl restart nginx
  133  systemctl restart nginx
  134  exit
  135  ls
  136  vi /etc/nginx/sites-enabled/default 
  137  systemctl restart nginx.service 
  138  tail /var/log/nginx/error.log 
  139  tail /var/log/nginx/access.log 
  140  cd /var/www/html/mail/
  141  ls
  142  ls -l
  143  cd config/
  144  ls
  145  cp -a config.inc.php.sample config.inc.php
  146  tail /var/log/nginx/error.log 
  147  cd ..
  148  ls
  149  vi index.php 
  150  cd config/
  151  ls
  152  mv config.inc.php config.inc.php.bak
  153  php
  154  ls
  155  cd ..
  156  ls
  157  php index.php 
  158  tail logs/
  159  ls -l logs/
  160  tail /var/log/nginx/error.log 
  161  tail /var/log/php8.2-fpm.log 
  162  vi /etc/nginx/sites-enabled/default 
  163  systemctl restart nginx
  164  apt install php-dom php-xml php-intl
  165  systemctl restart php8.2-fpm.service 
  174  vi mail/config/config.inc.php
  197  vi /etc/nginx/sites-enabled/default 
  198  systemctl restart nginx
  199  vi /etc/nginx/sites-enabled/default 
  200  systemctl restart nginx
  201  tail /var/log/nginx/error.log 
  203  ls
  204  vi /etc/nginx/sites-enabled/default 
  206  systemctl restart nginx
  207  tail /var/log/nginx/error.log 
  213  cd /etc/nginx/sites-enabled/
  214  ls
  215  cp postfixadmin mail
  216  vi mail 
  217  systemctl restart nginx
  218  tail /var/log/nginx/error.log 
  219  ls -l /opt/www/mail/public_html/
  220  vi mail 
  221  systemctl restart nginx
  222  ls -l /opt/www/mail/
  223  tail /var/log/nginx/error.log 
  224  vi mail
  225  systemctl restart nginx
  226  cd /opt/www/
  227  ls
  228  cd mail/
  229  ls
  230  ls
  231  vi config/config.inc.php
  232  vi /opt/www/postfixadmin/config.local.php 
  233  tail logs/errors.log 
  234  journalctl -u dovecot.service -n 20 --no-pager
  235  ls
  236  vi /etc/dovecot/dovecot-sql.conf.ext 
  237  journalctl -u dovecot.service -n 20 --no-pager
  238  ls
  239  vi /etc/dovecot/dovecot-sql.conf.ext 
  240  tail logs/errors.log 
  241  apt install sqlite3
  242  sqlite3 /var/vmail/postfixadmin.db 
  243  ls
  244  cd plugins/
  245  ls
  246  cd password/
  247  ls
  248  cp config.inc.php.dist config.inc.php
  249  vi config.inc.php
  259  ls -l /etc/ssl/private/postfix.key
  260  ls -l /root/.acme.sh/mail.drsvps.2xinxian.top_ecc/mail.drsvps.2xinxian.top.key
  261  vi /etc/dovecot/conf.d/10-master.conf 
  262  systemctl restart dovecot.service 
  263  journalctl -u dovecot.service -n 20 --no-pager
  264  chown dovecot /root/.acme.sh/mail.drsvps.2xinxian.top_ecc/mail.drsvps.2xinxian.top.key
  265  journalctl -u dovecot.service -n 20 --no-pager
  266  cd /etc/nginx/sites-enabled/
  267  ls
  268  vi mail 
  269  nginx -t
  270  nginx -s reload
  271  vi /etc/dovecot/conf.d/10-ssl.conf 
  272  vi /etc/dovecot/conf.d/10-auth.conf
  273  systemctl restart dovecot.s
  274  systemctl restart dovecot.service 
  275  vi /etc/dovecot/conf.d/10-auth.conf
  276  vi /etc/dovecot/conf.d/10-master.conf 
  279  systemctl restart dovecot.service 
  283  vi /etc/postfix/sqlite_virtual_alias_maps.cf
  284  sqlite3 /var/vmail/postfixadmin.db 
  285  ls -l /var/vmail/postfixadmin.db
  286  vi /etc/postfix/sqlite_virtual_alias_maps.cf
  287  systemctl restart postfix dovecot.service 
  288  journalctl -u postfix@-.service -n 20 --no-pager
  289  postmap -q he@drsvps.2xinxian.top sqlite:/etc/postfix/sql/sqlite_virtual_alias_maps.cf
  290  postmap -q he@drsvps.2xinxian.top sqlite:/etc/postfix/sqlite_virtual_alias_maps.cf
  297  journalctl -u postfix@-.service -n 20 --no-pager
  322  apt install postfix-sqlite
  323  ls -l a /var/vmail/
  324  journalctl -u postfix@-.service -n 20 --no-pager
  327  vi /etc/postfix/master.cf
  328  sqlite3 /var/vmail/postfixadmin.db 'PRAGMA journal_mode=delete;'
  329  cd /opt/www/mail/
  330  grep -rnw ./ -e "journal_mode"
  331  vi program/lib/Roundcube/db/sqlite.php
  332  journalctl -u postfix@-.service -n 20 --no-pager
  336  vi /etc/dovecot/conf.d/10-ssl.conf 
  337  vi /etc/dovecot/conf.d/10-auth.conf 
  338  systemctl restart dovecot
  339  vi config/config.inc.php

参考:

Roundcube - Server Error: UID COPY: The folder could not be found - create_default_folders

问题:在 Windows 里尝试安装 Roundcube Webmail ,但在用户登录后作邮件删除操作时,会提示错误:Server Error: UID COPY: The folder could not be found

解决:在 Roundcube 的 config.php 配置文件中,新增一行 $config['create_default_folders'] = true; 即可。

参考:https://www.roundcubeforum.net/index.php?topic=22955.0

iredmail - 通过 curl 来增加域名

需求:从一个含用域名列表的文本文件中逐行读取,通过 curl 提交给 iredadmin

尝试:

##
# Configurations.
##

rm tmpcs.txt
rm cookie

# Path to temporary file which will store your cookie data.
cookie_path=cookie

username=postmaster@anqun.org
password=ps88888888
login_url="https://mail.anqun.org/iredadmin/login"
create_url="https://mail.anqun.org/iredadmin/create/domain"
# action_url="$create_url/$domainname"

##
# Logic. Most likely you shouldn't change here anything.
##

curl -i -b $cookie_path -c $cookie_path -d "username=$username&password=$password" "$login_url"

curl -i -b $cookie_path -c $cookie_path -o tmpcs.txt --request GET "$create_url"

csrf_token=$(grep -oP '(?<=<input type="hidden" name="csrf_token" value=")[^"]*' tmpcs.txt)


while read -r line; do
   # 使用该行内容作为变量值来执行 cURL 命令
   data="csrf_token=$csrf_token&domainName=$line&cn=&submit_add_domain=Add"
   curl -i --cookie cookie --data "${data}" "$create_url"
done < domain.txt

初试 GPT-3.5 Poe 助手

约在一年前,王亮建议我多了解一下当时热门的 ChatGPT ,因为他觉得好玩,且较多人有这方面的需求。我不以为然,因为当时我觉得用谷歌搜索就够了,不必额外打开另一个页面或软件来做同一件事。

过年时,有个客户要求在阿里云的虚拟机上安装 FreeBSD 9.3 系统。FreeBSD 9.3 系统版本较老,是约在十年前发布的,阿里云官方提供的 FreeBSD 9.3 系统模板中,最低版本是 FreeBSD 11。我在年初一,尝试用常规的方法来安装 FreeBSD 9.3,但遇到了“拦路虎”—— FreeBSD 9.3 里自带的 VirtIO 驱动无法识别到阿里云新版本的虚拟机硬盘。经翻查资料,知道阿里云官方是提供了适合 FreeBSD 11 和 12 系统使用的 VirtIO 补丁,但没有旧版本 FreeBSD 9.3 的。

我要解决的问题,是如何修改阿里云的补丁,让它能在 FreeBSD 9.3 系统里使用。会读,会改程序代码,这是程序员必备的技能,但我仅是个“民工”,如同在电脑城里组装电脑的“师傅”,是装装 Windows 系统的菜鸟而已。哪怕是只有几行,几十个英文单词的代码,我都看不懂,不知道那是干什么用的。因为不知道怎么入手,很难用谷歌搜索关键字来查找到解决方法。我迫切地希望有个“老师”来给我讲解程序的代码。我想起 Poe 的“助手” ,抱着试试看的心态,一个问题接一个地向它提问,它解答了,且效果令我惊奇。我以前买过如《计算机C语音入门》之类的书,但根本没看懂,没学到一点儿的C语言编程知识,更没有实践紡程过,但现在“助手”它能即时讲解,内容简要并有指引性,我觉得它很实用,且3.5版本的 GPT 现在是免费的。

在这两个月的时间里,我先后两次通过工单请求阿里云客服让工程师花点时间为 FreeBSD 9.3 写个补丁,但他们拒绝了,说那是个很老的系统,新的虚拟化环境不支持,要用就得用老的虚拟机。阿里云官方不愿意写补丁,我又不好意思去 FreeBSD 官方社区里问,因为那儿写了,“结束支持的系统版本最好不要提问”。我只好每天,或隔几天,或在睡觉前,又或者在五、六点早醒时,断续着,在“助手”的帮助下,不断地尝试办法,推进测试的进度。例如,先从 FreeBSD 9.3 内核中的重编译过程中,剥离掉 VirtIO 模块,这样可以减少测试时编译所花的时间,仅重点测试 VirtIO 模块的编译和加载结果。然后又在不同的 FreeBSD 版本和不同的主机商虚拟环境中,测试 VirtIO 官方补丁的结果。最后,不断地在 VirtIO 补丁的程序代码中添加上 printf 的打印输出信息,看看驱动程序在加载过程中的逻辑和结果。得益于“助手”和谷歌搜索,滚泥水般反复测试,在约两个月后,我在阿里云实机测试,终于能成功运行 FreeBSD 9.3 系统。

在这件事情里,我没有写出程序代码,但在 GPT 助手的讲解和引导下,经过很多次的实机测试,再以测试结果中的关键词不断地在谷歌里搜索,最后查找到网友的解决方案。我对 GPT 助手的“博学多才”很惊讶,更难得的是,它“诲人不倦”啊,能一步步地为我讲解程序代码里的逻辑和函数(作用)。我是个“小白”,我对计算机编程是零基础的,但“助手”它能在我的普通提问中,让我了解了“中断”、“向量”等名词。如果这是在现实中,估计老师会对我的提问感到厌烦甚至是动怒,因为有时我是傻瓜般来回地提问。

GPT “助手”能给普通人在学习和了解知识上带来明显的效果。我希望以后能使用到它的场合越来越多,希望它能给社会带来普遍性的好处。