VirtualBox

Changeset 98067 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Jan 12, 2023 11:04:34 PM (2 years ago)
Author:
vboxsync
Message:

Main/HostDnsServiceLinux.cpp: Some @todos and cleanups. bugref:10255

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp

    r96407 r98067  
    6767class FileDescriptor
    6868{
    69     public:
    70     FileDescriptor(int d = -1):fd(d){}
     69public:
     70    FileDescriptor(int d = -1)
     71        : fd(d)
     72    {}
    7173
    7274    virtual ~FileDescriptor() {
     
    7779    int fileDescriptor() const {return fd;}
    7880
    79     protected:
     81protected:
    8082    int fd;
    8183};
    8284
    8385
    84 class AutoNotify:public FileDescriptor
    85 {
    86     public:
     86class AutoNotify : public FileDescriptor
     87{
     88public:
    8789    AutoNotify()
    8890    {
     
    119121int HostDnsServiceLinux::monitorThreadProc(void)
    120122{
     123    /*
     124     * inotify initialization
     125     *
     126     * Note! Ignoring failures here is safe, because poll will ignore entires
     127     *       with negative fd values.
     128     */
    121129    AutoNotify a;
    122 
     130    int wd[2];
     131    wd[0] = inotify_add_watch(a.fileDescriptor(),
     132                              g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF);
     133
     134    /* If /etc/resolv.conf exists we want to listen for movements: because
     135       # mv /etc/resolv.conf ...
     136       won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1].
     137
     138       Because on some distributions /etc/resolv.conf is a symlink, wd[0] can't detect
     139       deletion, it's recognizible on directory level (wd[1]) only. */
     140    wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
     141                              wd[0] == -1 ? IN_MOVED_TO | IN_CREATE : IN_MOVED_FROM | IN_DELETE);
     142
     143    /*
     144     * Create a socket pair for signalling shutdown via (see monitorThreadShutdown).
     145     */
    123146    int rc = socketpair(AF_LOCAL, SOCK_DGRAM, 0, g_DnsMonitorStop);
    124147    AssertMsgReturn(rc == 0, ("socketpair: failed (%d: %s)\n", errno, strerror(errno)), E_FAIL);
    125148
     149    /* automatic cleanup tricks */
    126150    FileDescriptor stopper0(g_DnsMonitorStop[0]);
    127151    FileDescriptor stopper1(g_DnsMonitorStop[1]);
    128152
     153    /*
     154     * poll initialization:
     155     */
    129156    pollfd polls[2];
    130157    RT_ZERO(polls);
     
    138165    onMonitorThreadInitDone();
    139166
    140     int wd[2];
    141     wd[0] = wd[1] = -1;
    142     /* inotify inialization */
    143     wd[0] = inotify_add_watch(a.fileDescriptor(),
    144                               g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE|IN_DELETE_SELF);
    145 
    146     /**
    147      * If /etc/resolv.conf exists we want to listen for movements: because
    148      * # mv /etc/resolv.conf ...
    149      * won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1].
    150      *
    151      * Because on some distributions /etc/resolv.conf is link, wd[0] can't detect deletion,
    152      * it's recognizible on directory level (wd[1]) only.
    153      */
    154     wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
    155                               wd[0] == -1 ? IN_MOVED_TO|IN_CREATE : IN_MOVED_FROM|IN_DELETE);
    156 
    157     struct InotifyEventWithName combo;
    158     while(true)
     167    /*
     168     * The monitoring loop.
     169     */
     170    for (;;)
    159171    {
    160         rc = poll(polls, 2, -1);
     172        rc = poll(polls, RT_ELEMENTS(polls), -1 /*infinite timeout*/);
    161173        if (rc == -1)
    162174            continue;
    163175
    164         AssertMsgReturn(   ((polls[0].revents & (POLLERR|POLLNVAL)) == 0)
    165                         && ((polls[1].revents & (POLLERR|POLLNVAL)) == 0),
    166                            ("Debug Me"), VERR_INTERNAL_ERROR);
     176        AssertMsgReturn(   (polls[0].revents & (POLLERR | POLLNVAL)) == 0
     177                        && (polls[1].revents & (POLLERR | POLLNVAL)) == 0, ("Debug Me"), VERR_INTERNAL_ERROR);
    167178
    168179        if (polls[1].revents & POLLIN)
     
    171182        if (polls[0].revents & POLLIN)
    172183        {
     184            /*
     185             * Read the notification event.
     186             */
     187            /** @todo r=bird: This is buggy in that it somehow assumes we'll only get
     188             *        one event here.  But since we're waiting on two different DELETE
     189             *        events for both a specific file and its parent directory, we're likely
     190             *        to get two DELETE events at the same time. */
     191            struct InotifyEventWithName combo;
    173192            RT_ZERO(combo);
    174             ssize_t r = read(polls[0].fd, static_cast<void *>(&combo), sizeof(combo));
     193            combo.e.wd = -42; /* avoid confusion on the offchance that wd[0] or wd[1] is zero. */
     194
     195            ssize_t r = read(polls[0].fd, &combo, sizeof(combo));
    175196            RT_NOREF(r);
    176197
     
    178199            {
    179200                if (combo.e.mask & IN_CLOSE_WRITE)
    180                 {
    181201                    readResolvConf();
    182                 }
    183202                else if (combo.e.mask & IN_DELETE_SELF)
    184203                {
    185204                    inotify_rm_watch(a.fileDescriptor(), wd[0]); /* removes file watcher */
    186                     inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
    187                                       IN_MOVED_TO|IN_CREATE); /* alter folder watcher */
     205                    int wd2 = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
     206                                                IN_MOVED_TO|IN_CREATE); /* alter folder watcher */
     207                    Assert(wd2 == wd[1]); RT_NOREF(wd2); /* ASSUMES wd[1] will be updated */
    188208                }
    189209                else if (combo.e.mask & IN_IGNORED)
    190                 {
    191210                    wd[0] = -1; /* we want receive any events on this watch */
    192                 }
    193211                else
    194212                {
    195                     /**
     213                    /*
    196214                     * It shouldn't happen, in release we will just ignore in debug
    197215                     * we will have to chance to look at into inotify_event
     
    202220            else if (combo.e.wd == wd[1])
    203221            {
    204                 if (   combo.e.mask & IN_MOVED_FROM
    205                     || combo.e.mask & IN_DELETE)
     222                if (combo.e.mask & (IN_DELETE | IN_MOVED_FROM))
    206223                {
    207224                    if (g_ResolvConf == combo.e.name)
    208225                    {
    209                         /**
    210                          * Our file has been moved so we should change watching mode.
     226                        /*
     227                         * Our file has been moved or deleted so we should change watching mode.
    211228                         */
    212229                        inotify_rm_watch(a.fileDescriptor(), wd[0]);
    213230                        wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
    214                                                   IN_MOVED_TO|IN_CREATE);
     231                                                  IN_MOVED_TO | IN_CREATE);
    215232                        AssertMsg(wd[1] != -1,
    216233                                  ("It shouldn't happen, further investigation is needed\n"));
     
    219236                else
    220237                {
    221                     AssertMsg(combo.e.mask & (IN_MOVED_TO|IN_CREATE),
    222                               ("%RX32 event isn't expected, we are waiting for IN_MOVED|IN_CREATE\n",
    223                                combo.e.mask));
     238                    AssertMsg(combo.e.mask & (IN_MOVED_TO | IN_CREATE),
     239                              ("%RX32 event isn't expected, we are waiting for IN_MOVED|IN_CREATE\n", combo.e.mask));
    224240                    if (g_ResolvConf == combo.e.name)
    225241                    {
    226242                        AssertMsg(wd[0] == -1, ("We haven't removed file watcher first\n"));
    227243
    228                         /* alter folder watcher*/
    229                         wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(),
    230                                                   IN_MOVED_FROM|IN_DELETE);
     244                        /* alter folder watcher: */
     245                        wd[1] = inotify_add_watch(a.fileDescriptor(),
     246                                                  g_EtcFolder.c_str(),
     247                                                  IN_MOVED_FROM | IN_DELETE);
    231248                        AssertMsg(wd[1] != -1, ("It shouldn't happen.\n"));
    232249
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette