在Mint 16中当按下光驱的弹出按钮后桌面上的光驱图标没有自动消失的有关问题解决

在Mint 16中当按下光驱的弹出按钮后桌面上的光驱图标没有自动消失的问题解决

/*********************************************************************
 * Author  : Samson
 * Date    : 07/29/2014
 * Test platform:
 *              Mint 16
 *              GNU bash, version 4.2.45
 * *******************************************************************/

问题分析:

当按下存在光盘的光驱弹出按钮时,查看系统日志会有一个内核警告信息:
在mint中在/var/log/syslog中存在如下警告(错误)信息:
May 30 10:49:08 ufo kernel: [  147.793292] VFS: busy inodes on changed media or resized disk sr0
kernel表示这个问题是一个内核中报出的问题,VFS表示此问题是由虚拟文件系统触发的;
而此问题的本质是因为光驱的挂载点没有能够进行正常地umount造成的,可以在命令行使用mount命令查看到光驱的设备名sr0对应的mount点:
ufo@ufo:/var/log$ mount | grep sr0
/dev/sr0 on /media/ufo/Album VideoCDEx type iso9660 (ro,nosuid,nodev,uid=1000,gid=1000,iocharset=utf8,mode=0400,dmode=0500,uhelper=udisks2)

经在多个GNU Linux的上流及下流版本中进行测试,均存在此问题;

这个问题可能需要从内核进行解决,但是这TM将是一个很大的工程,巨坑呀…… 看代码……尝试修改……编译内核……内核替换……  折腾了几天,某些原因不再玩儿这条线了¥#@¥%%&……&

好吧,那再看看从应用层能不能解决这个玩意儿问题吧,发现当按下存在光盘的光驱弹出按钮时,桌面图标会变化,而且名称都变为CD Drive, 那只要找到图标变化的地方就应该能够进行umount操作了,而mint的管理桌面图标变化等操作的是nemo包,好吧,那就找找吧……&×

在nemo包中的 src/nemo-icon-view.c中找到了图标变化的相应函数:nemo_icon_view_file_changed()
经过调试,发现这是光驱图标发生变化的幕后凶手,然后再进行调试,找到了在桌面上的显示名称对应的结构,啊哈,这下终于能够修理你 :_)

直接贴代码吧,多说也没有什么必要了。
在nemo_icon_view_file_changed()中的原来的具体代码后添加如下代码:
    char nocd[] = "CD Drive";
        if(file->details->display_name != NULL && strncmp(file->details->display_name, nocd, strlen(nocd)) == 0)
        {
                char umountcmd[] = "umount `mount | grep /dev/sr0  | awk '{print $3}'`";
                char str2[] = "`mount | grep /dev/sr0 | awk '{print $4}'`";
                char str3[] = "`mount | grep /dev/sr0 | awk '{print $5}'`";
                char str4[] = "`mount | grep /dev/sr0 | awk '{print $6}'`";
                char mount[256] = {0};

                int ret = system(umountcmd);
                if(ret)
                {
                        sprintf(mount, "%s?%s ", umountcmd, str2);
                        ret  = system(mount);
                        if(ret)
                        {
                                sprintf(mount, "%s?%s?%s ", umountcmd, str2, str3);
                                ret  = system(mount);
                                if(ret)
                                {
                                        sprintf(mount, "%s?%s?%s?%s ", umountcmd, str2, str3, str4);
                                        ret  = system(mount);
                                        if(ret)
                                        {
                                                sprintf(mount, "%s?%s?%s?%s* ", umountcmd, str2, str3, str4);
                                                ret  = system(mount);
                                        }
                                }
                        }
                }
        }

那么再对以上代码稍微说明一下,umountcmd这个其实是对没有空格的光驱名已经足够了,而str2,str3,str4这是对有多个空格的光驱名而需要的。
细心的筒子们,后面的sprintf中的?是嘛意思? 其实就是个通配符,因为空格真TM的不知道杂个写到字符串中,转义/040 已经试过了,没有效果,只有用个?给替换了,有大侠若是对在这的空格能够进行处理的请给个回复呀,俺灰常想知道怎么破*_&
最后的sprintf中的*就是不想再取变态的空格名称的点了,直接通配弄死它。
用 ?和*的潜在问题是可能有一个U盘呀什么的类似的挂载点刚好是光驱的挂载名+任意字符,那么有可能弄死的就是其它设备了,但这事儿吧,概率真TM的还是相当小的。

PS: 修改后编译的时候会出错的,那么就请看上一篇中介绍的如何去解决了。
Done