Filesystem mounted on top of “/” is inaccessible - so why can it be unmounted with “umount /”?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












$ unshare -rm
# mount --bind /tmp /

# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0


This new mount does not change the physical directory which / refers to. See also /proc/self/root. Changing the per-process root directory is what what chroot does. When I access /, it still shows the contents of my ext4 root filesystem, not the tmpfs:



# stat -f /tmp --format %T
tmpfs
# stat -f / --format %T
ext2/ext3
# ls -l -d -i /tmp
22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
# ls -l -d -i /
2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /


Except that umount operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?



# umount /
# awk ' if ($2 == "/") print $0; ' < /proc/mounts
/dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0


Environment



$ uname -r # Kernel version
4.17.3-200.fc28.x86_64


System call trace



I tried repeating this with umount / run under strace -f, but it doesn't show anything more illuminating. umount just calls umount2(), and it doesn't pass any flags (the second parameter is zero).



# strace -f umount /
...
statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
umount2("/", 0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++






share|improve this question



























    up vote
    1
    down vote

    favorite












    $ unshare -rm
    # mount --bind /tmp /

    # awk ' if ($2 == "/") print $0; ' < /proc/mounts
    /dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
    tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0


    This new mount does not change the physical directory which / refers to. See also /proc/self/root. Changing the per-process root directory is what what chroot does. When I access /, it still shows the contents of my ext4 root filesystem, not the tmpfs:



    # stat -f /tmp --format %T
    tmpfs
    # stat -f / --format %T
    ext2/ext3
    # ls -l -d -i /tmp
    22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
    # ls -l -d -i /
    2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /


    Except that umount operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?



    # umount /
    # awk ' if ($2 == "/") print $0; ' < /proc/mounts
    /dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0


    Environment



    $ uname -r # Kernel version
    4.17.3-200.fc28.x86_64


    System call trace



    I tried repeating this with umount / run under strace -f, but it doesn't show anything more illuminating. umount just calls umount2(), and it doesn't pass any flags (the second parameter is zero).



    # strace -f umount /
    ...
    statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
    stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
    stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
    stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
    umount2("/", 0) = 0
    close(1) = 0
    close(2) = 0
    exit_group(0) = ?
    +++ exited with 0 +++






    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      $ unshare -rm
      # mount --bind /tmp /

      # awk ' if ($2 == "/") print $0; ' < /proc/mounts
      /dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
      tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0


      This new mount does not change the physical directory which / refers to. See also /proc/self/root. Changing the per-process root directory is what what chroot does. When I access /, it still shows the contents of my ext4 root filesystem, not the tmpfs:



      # stat -f /tmp --format %T
      tmpfs
      # stat -f / --format %T
      ext2/ext3
      # ls -l -d -i /tmp
      22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
      # ls -l -d -i /
      2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /


      Except that umount operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?



      # umount /
      # awk ' if ($2 == "/") print $0; ' < /proc/mounts
      /dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0


      Environment



      $ uname -r # Kernel version
      4.17.3-200.fc28.x86_64


      System call trace



      I tried repeating this with umount / run under strace -f, but it doesn't show anything more illuminating. umount just calls umount2(), and it doesn't pass any flags (the second parameter is zero).



      # strace -f umount /
      ...
      statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
      stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
      stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
      stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
      umount2("/", 0) = 0
      close(1) = 0
      close(2) = 0
      exit_group(0) = ?
      +++ exited with 0 +++






      share|improve this question













      $ unshare -rm
      # mount --bind /tmp /

      # awk ' if ($2 == "/") print $0; ' < /proc/mounts
      /dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0
      tmpfs / tmpfs rw,seclabel,nosuid,nodev 0 0


      This new mount does not change the physical directory which / refers to. See also /proc/self/root. Changing the per-process root directory is what what chroot does. When I access /, it still shows the contents of my ext4 root filesystem, not the tmpfs:



      # stat -f /tmp --format %T
      tmpfs
      # stat -f / --format %T
      ext2/ext3
      # ls -l -d -i /tmp
      22161 drwxrwxrwt. 44 nfsnobody nfsnobody 1000 Jul 19 09:49 /tmp
      # ls -l -d -i /
      2 dr-xr-xr-x. 19 nfsnobody nfsnobody 4096 Jul 7 09:21 /


      Except that umount operates on the tmpfs mount. How does this work - what is the difference between these two types of operation?



      # umount /
      # awk ' if ($2 == "/") print $0; ' < /proc/mounts
      /dev/mapper/alan_dell_2016-fedora / ext4 rw,seclabel,relatime 0 0


      Environment



      $ uname -r # Kernel version
      4.17.3-200.fc28.x86_64


      System call trace



      I tried repeating this with umount / run under strace -f, but it doesn't show anything more illuminating. umount just calls umount2(), and it doesn't pass any flags (the second parameter is zero).



      # strace -f umount /
      ...
      statfs("/", f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=10288440, f_bfree=2384614, f_bavail=1856230, f_files=2621440, f_ffree=2253065, f_fsid=val=[1557883181, 1665775425], f_namelen=255, f_frsize=4096, f_flags=ST_VALID) = 0
      stat("/sbin/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
      stat("/sbin/fs.d/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
      stat("/sbin/fs/umount.ext4", 0x7ffd79ccbb40) = -1 ENOENT (No such file or directory)
      umount2("/", 0) = 0
      close(1) = 0
      close(2) = 0
      exit_group(0) = ?
      +++ exited with 0 +++








      share|improve this question












      share|improve this question




      share|improve this question








      edited Jul 19 at 12:10
























      asked Jul 19 at 10:15









      sourcejedi

      18k22375




      18k22375




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote



          accepted










          Looking inside Linux v4.17, I think we can say umount on / is equivalent to umount on /... And /.. accesses the "top of [the] mountpoint pile".



          # stat -f / --format %T
          ext2/ext3
          # stat -f /.. --format %T
          tmpfs


          This obscure behaviour of .. seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").



          If you want to generalize this and define the behaviour implemented by umount on other mount points, making a comparison with .. does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).



          Kernel source code



          https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c



          See where path_mountpoint() calls follow_mount().



          /**
          * path_mountpoint - look up a path to be umounted
          * @nd: lookup context
          * @flags: lookup flags
          * @path: pointer to container for result
          *
          * Look up the given name, but don't attempt to revalidate the last component.
          * Returns 0 and "path" will be valid on success; Returns error otherwise.
          */
          static int
          path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)

          const char *s = path_init(nd, flags);
          int err;
          if (IS_ERR(s))
          return PTR_ERR(s);
          while (!(err = link_path_walk(s, nd)) &&
          (err = mountpoint_last(nd)) > 0)
          s = trailing_symlink(nd);
          if (IS_ERR(s))
          err = PTR_ERR(s);
          break;


          if (!err)
          *path = nd->path;
          nd->path.mnt = NULL;
          nd->path.dentry = NULL;
          follow_mount(path);

          terminate_walk(nd);
          return err;



          The comment for follow_mount() sounded like it was relevant to the question. And it mentions follow_dotdot() as the main user, which suggested this line of investigation.



          /*
          * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
          */
          static void follow_mount(struct path *path)

          while (d_mountpoint(path->dentry))
          struct vfsmount *mounted = lookup_mnt(path);
          if (!mounted)
          break;
          dput(path->dentry);
          mntput(path->mnt);
          path->mnt = mounted;
          path->dentry = dget(mounted->mnt_root);



          static int follow_dotdot(struct nameidata *nd)


          I had been thinking about how .. ("dotdot") could traverse from a mount point to its parent, e.g. /tmp/... But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp directory!






          share|improve this answer























            Your Answer







            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f457173%2ffilesystem-mounted-on-top-of-is-inaccessible-so-why-can-it-be-unmounted-wi%23new-answer', 'question_page');

            );

            Post as a guest






























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote



            accepted










            Looking inside Linux v4.17, I think we can say umount on / is equivalent to umount on /... And /.. accesses the "top of [the] mountpoint pile".



            # stat -f / --format %T
            ext2/ext3
            # stat -f /.. --format %T
            tmpfs


            This obscure behaviour of .. seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").



            If you want to generalize this and define the behaviour implemented by umount on other mount points, making a comparison with .. does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).



            Kernel source code



            https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c



            See where path_mountpoint() calls follow_mount().



            /**
            * path_mountpoint - look up a path to be umounted
            * @nd: lookup context
            * @flags: lookup flags
            * @path: pointer to container for result
            *
            * Look up the given name, but don't attempt to revalidate the last component.
            * Returns 0 and "path" will be valid on success; Returns error otherwise.
            */
            static int
            path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)

            const char *s = path_init(nd, flags);
            int err;
            if (IS_ERR(s))
            return PTR_ERR(s);
            while (!(err = link_path_walk(s, nd)) &&
            (err = mountpoint_last(nd)) > 0)
            s = trailing_symlink(nd);
            if (IS_ERR(s))
            err = PTR_ERR(s);
            break;


            if (!err)
            *path = nd->path;
            nd->path.mnt = NULL;
            nd->path.dentry = NULL;
            follow_mount(path);

            terminate_walk(nd);
            return err;



            The comment for follow_mount() sounded like it was relevant to the question. And it mentions follow_dotdot() as the main user, which suggested this line of investigation.



            /*
            * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
            */
            static void follow_mount(struct path *path)

            while (d_mountpoint(path->dentry))
            struct vfsmount *mounted = lookup_mnt(path);
            if (!mounted)
            break;
            dput(path->dentry);
            mntput(path->mnt);
            path->mnt = mounted;
            path->dentry = dget(mounted->mnt_root);



            static int follow_dotdot(struct nameidata *nd)


            I had been thinking about how .. ("dotdot") could traverse from a mount point to its parent, e.g. /tmp/... But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp directory!






            share|improve this answer



























              up vote
              2
              down vote



              accepted










              Looking inside Linux v4.17, I think we can say umount on / is equivalent to umount on /... And /.. accesses the "top of [the] mountpoint pile".



              # stat -f / --format %T
              ext2/ext3
              # stat -f /.. --format %T
              tmpfs


              This obscure behaviour of .. seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").



              If you want to generalize this and define the behaviour implemented by umount on other mount points, making a comparison with .. does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).



              Kernel source code



              https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c



              See where path_mountpoint() calls follow_mount().



              /**
              * path_mountpoint - look up a path to be umounted
              * @nd: lookup context
              * @flags: lookup flags
              * @path: pointer to container for result
              *
              * Look up the given name, but don't attempt to revalidate the last component.
              * Returns 0 and "path" will be valid on success; Returns error otherwise.
              */
              static int
              path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)

              const char *s = path_init(nd, flags);
              int err;
              if (IS_ERR(s))
              return PTR_ERR(s);
              while (!(err = link_path_walk(s, nd)) &&
              (err = mountpoint_last(nd)) > 0)
              s = trailing_symlink(nd);
              if (IS_ERR(s))
              err = PTR_ERR(s);
              break;


              if (!err)
              *path = nd->path;
              nd->path.mnt = NULL;
              nd->path.dentry = NULL;
              follow_mount(path);

              terminate_walk(nd);
              return err;



              The comment for follow_mount() sounded like it was relevant to the question. And it mentions follow_dotdot() as the main user, which suggested this line of investigation.



              /*
              * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
              */
              static void follow_mount(struct path *path)

              while (d_mountpoint(path->dentry))
              struct vfsmount *mounted = lookup_mnt(path);
              if (!mounted)
              break;
              dput(path->dentry);
              mntput(path->mnt);
              path->mnt = mounted;
              path->dentry = dget(mounted->mnt_root);



              static int follow_dotdot(struct nameidata *nd)


              I had been thinking about how .. ("dotdot") could traverse from a mount point to its parent, e.g. /tmp/... But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp directory!






              share|improve this answer

























                up vote
                2
                down vote



                accepted







                up vote
                2
                down vote



                accepted






                Looking inside Linux v4.17, I think we can say umount on / is equivalent to umount on /... And /.. accesses the "top of [the] mountpoint pile".



                # stat -f / --format %T
                ext2/ext3
                # stat -f /.. --format %T
                tmpfs


                This obscure behaviour of .. seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").



                If you want to generalize this and define the behaviour implemented by umount on other mount points, making a comparison with .. does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).



                Kernel source code



                https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c



                See where path_mountpoint() calls follow_mount().



                /**
                * path_mountpoint - look up a path to be umounted
                * @nd: lookup context
                * @flags: lookup flags
                * @path: pointer to container for result
                *
                * Look up the given name, but don't attempt to revalidate the last component.
                * Returns 0 and "path" will be valid on success; Returns error otherwise.
                */
                static int
                path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)

                const char *s = path_init(nd, flags);
                int err;
                if (IS_ERR(s))
                return PTR_ERR(s);
                while (!(err = link_path_walk(s, nd)) &&
                (err = mountpoint_last(nd)) > 0)
                s = trailing_symlink(nd);
                if (IS_ERR(s))
                err = PTR_ERR(s);
                break;


                if (!err)
                *path = nd->path;
                nd->path.mnt = NULL;
                nd->path.dentry = NULL;
                follow_mount(path);

                terminate_walk(nd);
                return err;



                The comment for follow_mount() sounded like it was relevant to the question. And it mentions follow_dotdot() as the main user, which suggested this line of investigation.



                /*
                * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
                */
                static void follow_mount(struct path *path)

                while (d_mountpoint(path->dentry))
                struct vfsmount *mounted = lookup_mnt(path);
                if (!mounted)
                break;
                dput(path->dentry);
                mntput(path->mnt);
                path->mnt = mounted;
                path->dentry = dget(mounted->mnt_root);



                static int follow_dotdot(struct nameidata *nd)


                I had been thinking about how .. ("dotdot") could traverse from a mount point to its parent, e.g. /tmp/... But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp directory!






                share|improve this answer















                Looking inside Linux v4.17, I think we can say umount on / is equivalent to umount on /... And /.. accesses the "top of [the] mountpoint pile".



                # stat -f / --format %T
                ext2/ext3
                # stat -f /.. --format %T
                tmpfs


                This obscure behaviour of .. seems to be permitted by POSIX. It only says "As a special case, in the root directory, dot-dot may refer to the root directory itself." (POSIX.1-2017, section 4.13 "Pathname Resolution").



                If you want to generalize this and define the behaviour implemented by umount on other mount points, making a comparison with .. does not work so well. The term "top of [the] mountpoint pile" still applies, although it doesn't sound like a very formal definition :).



                Kernel source code



                https://elixir.bootlin.com/linux/v4.17/source/fs/namei.c



                See where path_mountpoint() calls follow_mount().



                /**
                * path_mountpoint - look up a path to be umounted
                * @nd: lookup context
                * @flags: lookup flags
                * @path: pointer to container for result
                *
                * Look up the given name, but don't attempt to revalidate the last component.
                * Returns 0 and "path" will be valid on success; Returns error otherwise.
                */
                static int
                path_mountpoint(struct nameidata *nd, unsigned flags, struct path *path)

                const char *s = path_init(nd, flags);
                int err;
                if (IS_ERR(s))
                return PTR_ERR(s);
                while (!(err = link_path_walk(s, nd)) &&
                (err = mountpoint_last(nd)) > 0)
                s = trailing_symlink(nd);
                if (IS_ERR(s))
                err = PTR_ERR(s);
                break;


                if (!err)
                *path = nd->path;
                nd->path.mnt = NULL;
                nd->path.dentry = NULL;
                follow_mount(path);

                terminate_walk(nd);
                return err;



                The comment for follow_mount() sounded like it was relevant to the question. And it mentions follow_dotdot() as the main user, which suggested this line of investigation.



                /*
                * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
                */
                static void follow_mount(struct path *path)

                while (d_mountpoint(path->dentry))
                struct vfsmount *mounted = lookup_mnt(path);
                if (!mounted)
                break;
                dput(path->dentry);
                mntput(path->mnt);
                path->mnt = mounted;
                path->dentry = dget(mounted->mnt_root);



                static int follow_dotdot(struct nameidata *nd)


                I had been thinking about how .. ("dotdot") could traverse from a mount point to its parent, e.g. /tmp/... But I hadn't previously considered that doing so might "skip to [the] top of [the] mountpoint pile". This happens even if the top mount isn't the one that contains the original /tmp directory!







                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jul 19 at 12:00


























                answered Jul 19 at 11:23









                sourcejedi

                18k22375




                18k22375






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f457173%2ffilesystem-mounted-on-top-of-is-inaccessible-so-why-can-it-be-unmounted-wi%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Bahrain

                    Postfix configuration issue with fips on centos 7; mailgun relay