1 /*===========================================================================
2  *
3  *                            PUBLIC DOMAIN NOTICE
4  *               National Center for Biotechnology Information
5  *
6  *  This software/database is a "United States Government Work" under the
7  *  terms of the United States Copyright Act.  It was written as part of
8  *  the author's official duties as a United States Government employee and
9  *  thus cannot be copyrighted.  This software/database is freely available
10  *  to the public for use. The National Library of Medicine and the U.S.
11  *  Government have not placed any restriction on its use or reproduction.
12  *
13  *  Although all reasonable efforts have been taken to ensure the accuracy
14  *  and reliability of the software and data, the NLM and the U.S.
15  *  Government do not and cannot warrant the performance or results that
16  *  may be obtained by using this software or data. The NLM and the U.S.
17  *  Government disclaim all warranties, express or implied, including
18  *  warranties of performance, merchantability or fitness for any particular
19  *  purpose.
20  *
21  *  Please cite the author in any work or product based on this material.
22  *
23  * ===========================================================================
24  *
25  */
26 
27 #include <klib/defs.h>
28 #include <klib/log.h>
29 
30 #include "docker.h"
31 
32 #if CAN_HAVE_CONTAINER_ID
33 
34 #include <stdio.h>
35 #include <unistd.h>
36 
37 #include <kfs/file.h>
38 #include <kfs/directory.h>
39 
40 #define CGROUP_FILE_PATH "/proc/self/cgroup"
41 /* /proc/self/cgroup lines like this:
42  * 14:name=systemd:/docker/2b644fadb9fbf627caeede280d3d00e9c4cc59022ae4ee186a92c41e96eb8106
43  * ^ unimportant ^         ^--------------- this part is the container id ----------------^
44  */
45 #endif
46 
KConfig_Get_GUID_Add_Container(char * const value,size_t const value_size)47 int KConfig_Get_GUID_Add_Container(  char *const value
48                                    , size_t const value_size)
49 {
50 #if CAN_HAVE_CONTAINER_ID
51     if (value_size >= 12) {
52         char buffer[4096];
53         size_t inbuf = 0;
54         size_t nread = 0;
55         uint64_t pos = 0;
56         KFile const *fp = NULL;
57         KDirectory *ndir = NULL;
58         rc_t rc = 0;
59         bool good = false;
60 
61         rc = KDirectoryNativeDir(&ndir);
62         assert(rc == 0);
63 
64         rc = KDirectoryOpenFileRead(ndir, &fp, CGROUP_FILE_PATH);
65         KDirectoryRelease(ndir);
66         if (rc) {
67             LogErr(klogDebug, rc, "can not open " CGROUP_FILE_PATH);
68             return -1;
69         }
70         while (good == false && (rc = KFileRead(fp, pos, buffer + inbuf, sizeof(buffer) - inbuf, &nread)) == 0 && nread > 0)
71         {
72             size_t i = 0, start = 0;
73 
74             pos += nread;
75             inbuf += nread;
76             for (i = 0; i < inbuf; ) {
77                 int const ch = buffer[i++];
78                 if (ch == ':') {
79                     start = i;
80                     continue;
81                 }
82                 if (ch == '\n') {
83                     char const *id = &buffer[start];
84                     size_t len = (i - 1) - start;
85                     if (len >= 8 && strncmp(id, "/docker/", 8) == 0) {
86                         id += 8; len -= 8;
87                         pLogMsg(klogDebug, "container-id: $(id)", "id=%.*s", (int)(len), id);
88                         if (len >= 12) {
89                             memmove(value + (value_size - 12), id, 12);
90                             good = true;
91                             break;
92                         }
93                     }
94                     inbuf -= i;
95                     memmove(buffer, buffer + i, inbuf);
96                     i = 0;
97                 }
98             }
99         }
100         KFileRelease(fp);
101         return good ? 0 : -1;
102     }
103 #endif
104     return -1;
105 }
106