关于Linux 系统程序(进程)自动升级的方法

        项目有一个CS架构的客户端程序需要远程升级,client从server下载升级包,升级包最好做一个校验,避免文件出错导致升级失败。一般用md5校验,下载的升级包一般包含成一个文本文件和一个升级文件,文本文件中记录升级文件的md5值。client端接收到升级包后计算升级包里面的升级文件的MD5值,然后与文本文件里面的MD5比较,MD5值不相等,说明文件错误,不能用来升级。

        升级包下载好后,关键是如何加载,升级是要下载当前的client进程,然后加载新的client进程。原来我们是在client进程里面调用一个shell脚本,在这个脚本里面执行卸载老进程,加载新进程的工作。该方法功能上可用,但会有一个资源泄漏的隐患。

        Client调用shell脚本是通过fork实现的,本质上shell是client进程的子进程,然后shell里面加载的client进程又是shell的子进程。我们知道子进程是复制父进程的资源的,比如client进程打开了一个文件句柄,这个文件句柄最终会传递到新加载的client进程中,新加载的client里面功能执行后,又会重新打开一个文件句柄。反复多次升级后 client进程占用的句柄会越积越多。

        为了避免上述情况,需要用其它的进程加载新下载的Client。可以设计一个专门的deamon守护进程,负责加载Client。也可以用系统的crond,Client进程下载后自己退出,然后通过crond周期检查,发现client进程不走时,加载Client.

       另外句柄继承也可以通过close-on-exec机制解决,在创建socket时增加SOCK_CLOEXEC,同样在文件的句柄Open打开时增加O_CLOEXEC

       SOCKET ss = ::socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);

      int fd = open(“foo.txt”,O_RDONLY | O_CLOEXEC);

     或者通过fcntl设置

      int flags = fcntl(fd, F_GETFD);  
      flags |= FD_CLOEXEC;  
      fcntl(fd, F_SETFD, flags); 

 

     

 

 

       

 

你可能感兴趣的:(关于Linux 系统程序(进程)自动升级的方法)