lkml.org 
[lkml]   [2018]   [Dec]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 062/142] perf tools: Restore proper cwd on return from mnt namespace
    Date
    4.19-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    [ Upstream commit b01c1f69c8660eaeab7d365cd570103c5c073a02 ]

    When reporting on 'record' server we try to retrieve/use the mnt
    namespace of the profiled tasks. We use following API with cookie to
    hold the return namespace, roughly:

    nsinfo__mountns_enter(struct nsinfo *nsi, struct nscookie *nc)
    setns(newns, 0);
    ...
    new ns related open..
    ...
    nsinfo__mountns_exit(struct nscookie *nc)
    setns(nc->oldns)

    Once finished we setns to old namespace, which also sets the current
    working directory (cwd) to "/", trashing the cwd we had.

    This is mostly fine, because we use absolute paths almost everywhere,
    but it screws up 'perf diff':

    # perf diff
    failed to open perf.data: No such file or directory (try 'perf record' first)
    ...

    Adding the current working directory to be part of the cookie and
    restoring it in the nsinfo__mountns_exit call.

    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Krister Johansen <kjlx@templeofstupid.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Fixes: 843ff37bb59e ("perf symbols: Find symbols in different mount namespace")
    Link: http://lkml.kernel.org/r/20181101170001.30019-1-jolsa@kernel.org
    [ No need to check for NULL args for free(), use zfree() for struct members ]
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    tools/perf/util/namespaces.c | 17 +++++++++++++++--
    tools/perf/util/namespaces.h | 1 +
    2 files changed, 16 insertions(+), 2 deletions(-)

    diff --git a/tools/perf/util/namespaces.c b/tools/perf/util/namespaces.c
    index cf8bd123cf73..aed170bd4384 100644
    --- a/tools/perf/util/namespaces.c
    +++ b/tools/perf/util/namespaces.c
    @@ -18,6 +18,7 @@
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    +#include <asm/bug.h>

    struct namespaces *namespaces__new(struct namespaces_event *event)
    {
    @@ -186,6 +187,7 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,
    char curpath[PATH_MAX];
    int oldns = -1;
    int newns = -1;
    + char *oldcwd = NULL;

    if (nc == NULL)
    return;
    @@ -199,9 +201,13 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,
    if (snprintf(curpath, PATH_MAX, "/proc/self/ns/mnt") >= PATH_MAX)
    return;

    + oldcwd = get_current_dir_name();
    + if (!oldcwd)
    + return;
    +
    oldns = open(curpath, O_RDONLY);
    if (oldns < 0)
    - return;
    + goto errout;

    newns = open(nsi->mntns_path, O_RDONLY);
    if (newns < 0)
    @@ -210,11 +216,13 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,
    if (setns(newns, CLONE_NEWNS) < 0)
    goto errout;

    + nc->oldcwd = oldcwd;
    nc->oldns = oldns;
    nc->newns = newns;
    return;

    errout:
    + free(oldcwd);
    if (oldns > -1)
    close(oldns);
    if (newns > -1)
    @@ -223,11 +231,16 @@ void nsinfo__mountns_enter(struct nsinfo *nsi,

    void nsinfo__mountns_exit(struct nscookie *nc)
    {
    - if (nc == NULL || nc->oldns == -1 || nc->newns == -1)
    + if (nc == NULL || nc->oldns == -1 || nc->newns == -1 || !nc->oldcwd)
    return;

    setns(nc->oldns, CLONE_NEWNS);

    + if (nc->oldcwd) {
    + WARN_ON_ONCE(chdir(nc->oldcwd));
    + zfree(&nc->oldcwd);
    + }
    +
    if (nc->oldns > -1) {
    close(nc->oldns);
    nc->oldns = -1;
    diff --git a/tools/perf/util/namespaces.h b/tools/perf/util/namespaces.h
    index cae1a9a39722..d5f46c09ea31 100644
    --- a/tools/perf/util/namespaces.h
    +++ b/tools/perf/util/namespaces.h
    @@ -38,6 +38,7 @@ struct nsinfo {
    struct nscookie {
    int oldns;
    int newns;
    + char *oldcwd;
    };

    int nsinfo__init(struct nsinfo *nsi);
    --
    2.19.1


    \
     
     \ /
      Last update: 2018-12-14 13:41    [W:4.666 / U:0.232 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site