]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Cleanup: Integrate similar code to cgroup_get_uid_gid_from_procfs().
authorKen'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
Mon, 8 Jun 2009 08:18:43 +0000 (17:18 +0900)
committerDhaval Giani <dhaval@linux.vnet.ibm.com>
Mon, 8 Jun 2009 09:03:25 +0000 (14:33 +0530)
CHANGELOG of v2.1:
================
* Rebase the patch for commit '340feae163c4797a6cb1247b3812c1ccdc52fa41'.

There are some similar functions for getting process's data (uid, gid) from
/proc/<pid>/status file, so this patch integrates these functions into one
cgroup_get_uid_gid_from_procfs().

Signed-off-by: Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
Reviewed-By: Jan Safranek <jsafrane@redhat.com>
Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
src/api.c
src/daemon/cgrulesengd.c
src/daemon/cgrulesengd.h
src/libcgroup-internal.h
src/libcgroup.map
src/tools/cgclassify.c

index 9a379d6186a46dcb3d941d60102a262023c7a03b..ccea89c0ba63c40ec4926f34d3d3aaa93f33912f 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -2473,3 +2473,58 @@ int cgroup_get_task_begin(char *cgroup, char *controller, void **handle,
 
        return ret;
 }
+
+/**
+ * Get process data (euid and egid) from /proc/<pid>/status file.
+ * @param pid: The process id
+ * @param euid: The uid of param pid
+ * @param egid: The gid of param pid
+ * @return 0 on success, > 0 on error.
+ */
+int cgroup_get_uid_gid_from_procfs(pid_t pid, uid_t *euid, gid_t *egid)
+{
+       FILE *f;
+       char path[FILENAME_MAX];
+       char buf[4092];
+       uid_t ruid, suid, fsuid;
+       gid_t rgid, sgid, fsgid;
+       bool found_euid = false;
+       bool found_egid = false;
+
+       sprintf(path, "/proc/%d/status", pid);
+       f = fopen(path, "r");
+       if (!f)
+               return ECGROUPNOTEXIST;
+
+       while (fgets(buf, sizeof(buf), f)) {
+               if (!strncmp(buf, "Uid:", 4)) {
+                       if (sscanf((buf + 5), "%d%d%d%d", &ruid, euid,
+                                       &suid, &fsuid) != 4)
+                               break;
+                       cgroup_dbg("Scanned proc values are %d %d %d %d\n",
+                               ruid, *euid, suid, fsuid);
+                       found_euid = true;
+               } else if (!strncmp(buf, "Gid:", 4)) {
+                       if (sscanf((buf + 5), "%d%d%d%d", &rgid, egid,
+                                       &sgid, &fsgid) != 4)
+                               break;
+                       cgroup_dbg("Scanned proc values are %d %d %d %d\n",
+                               rgid, *egid, sgid, fsgid);
+                       found_egid = true;
+               }
+               if (found_euid && found_egid)
+                       break;
+       }
+       fclose(f);
+       if (!found_euid || !found_egid) {
+               /*
+                * This method doesn't match the file format of
+                * /proc/<pid>/status. The format has been changed
+                * and we should catch up the change.
+                */
+               cgroup_dbg("The invlid file format of /proc/%d/status.\n", pid);
+               return ECGFAIL;
+       }
+       return 0;
+}
+
index 1a7b3217ef34879c694858e47ce0a6607d69891f..4c71283d5a74ee1706fe9b8340a7065d59b65d7f 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "libcgroup.h"
 #include "cgrulesengd.h"
+#include "../libcgroup-internal.h"
 
 #include <errno.h>
 #include <stdarg.h>
@@ -140,52 +141,6 @@ void flog(int level, const char *format, ...)
        }
 }
 
-static int cgre_get_euid_egid_from_status(pid_t pid, uid_t *euid, gid_t *egid)
-{
-       /* Handle for the /proc/PID/status file */
-       FILE *f;
-
-       /* Path for /proc/PID/status file */
-       char path[FILENAME_MAX];
-
-       /* Temporary buffer */
-       char buf[4092];
-
-       /* UID data */
-       uid_t ruid, suid, fsuid;
-
-       /* GID data */
-       gid_t rgid, sgid, fsgid;
-
-       /*
-        * First, we need to open the /proc/PID/status file so that we can
-        * get the effective UID and GID for the process that we're working
-        * on.  This process is probably not us, so we can't just call
-        * geteuid() or getegid().
-        */
-       sprintf(path, "/proc/%d/status", pid);
-       f = fopen(path, "r");
-       if (!f) {
-               flog(LOG_WARNING, "Failed to open %s", path);
-               return 1;
-       }
-
-       /* Have the eUID, need to find the eGID. */
-       memset(buf, '\0', sizeof(buf));
-       while (fgets(buf, sizeof(buf), f)) {
-               if (!strncmp(buf, "Uid:", 4)) {
-                       sscanf((buf + 5), "%d%d%d%d", &ruid, euid,
-                               &suid, &fsuid);
-               } else if (!strncmp(buf, "Gid:", 4)) {
-                       sscanf((buf + 5), "%d%d%d%d", &rgid, egid,
-                               &sgid, &fsgid);
-               }
-               memset(buf, '\0', sizeof(buf));
-       }
-       fclose(f);
-       return 0;
-}
-
 struct parent_info {
        __u64 timestamp;
        pid_t pid;
@@ -325,10 +280,13 @@ int cgre_process_event(const struct proc_event *ev, const int type)
        default:
                break;
        }
-       if (cgre_get_euid_egid_from_status(pid, &euid, &egid))
-               /* cgre_get_euid_egid_from_status() returns 1 if it fails to
-                * open /proc/<pid>/status file and that is not a problem. */
+       ret = cgroup_get_uid_gid_from_procfs(pid, &euid, &egid);
+       if (ret == ECGROUPNOTEXIST)
+               /* cgroup_get_uid_gid_from_procfs() returns ECGROUPNOTEXIST
+                * if a process finished and that is not a problem. */
                return 0;
+       else if (ret)
+               return ret;
 
        /*
         * Now that we have the UID, the GID, and the PID, we can make a call
index 1840143afcf05ec3a36cd7868abbb65ea7f11a20..506cb5d346d789748c7c74c6c288d073510b2d26 100644 (file)
@@ -31,13 +31,6 @@ __BEGIN_DECLS
 #define __USE_GNU
 #endif
 
-/* A simple macro for printing messages only when CGROUP_DEBUG is defined. */
-#ifdef CGROUP_DEBUG
-  #define cgroup_dbg(a...) printf(a)
-#else
-  #define cgroup_dbg(a...) do {} while (0)
-#endif /* CGROUP_DEBUG */
-
 /* The following ten macros are all for the Netlink code. */
 #define SEND_MESSAGE_LEN (NLMSG_LENGTH(sizeof(struct cn_msg) + \
        sizeof(enum proc_cn_mcast_op)))
index 9e69f10e4de59793f0d98572ed82c6ef6e12f230..a80ae389bdc32f9b09594445a8be1f55e3a29366 100644 (file)
@@ -90,6 +90,8 @@ struct cgroup_rule_list {
 
 /* Internal API */
 char *cg_build_path(char *name, char *path, char *type);
+int cgroup_get_uid_gid_from_procfs(pid_t pid, uid_t *euid, gid_t *egid);
+
 
 /*
  * config related API
index 539687f06ce7abdb86b2dc63adf1d837b1b8f5a6..8d330e61eb27c113f3cdaa4d61307066ed793c5b 100644 (file)
@@ -63,4 +63,5 @@ global:
        cgroup_read_stats_next;
        cgroup_read_stats_end;
        cgroup_get_controller;
+       cgroup_get_uid_gid_from_procfs;
 } CGROUP_0.33;
index de105107184bfbffe915bfb2184b6ee4db19c135..ceaca34c0f84f436ed5db48ea0299690da7d20a5 100644 (file)
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <errno.h>
 #include <libcgroup.h>
+#include <libcgroup-internal.h>
 #include <limits.h>
 #include <pwd.h>
 #include <unistd.h>
 
 #define TEMP_BUF       81
 
-/*
- * Go through /proc/<pid>/status file to determine the euid of the
- * process.
- * It returns 0 on success and negative values on failure.
- */
-
-int euid_of_pid(pid_t pid)
-{
-       FILE *fp;
-       char path[FILENAME_MAX];
-       char buf[TEMP_BUF];
-       uid_t ruid, euid, suid, fsuid;
-
-       sprintf(path, "/proc/%d/status", pid);
-       fp = fopen(path, "r");
-       if (!fp) {
-               cgroup_dbg("Error in opening file %s:%s\n", path,
-                               strerror(errno));
-               return -1;
-       }
-
-       while (fgets(buf, TEMP_BUF, fp)) {
-               if (!strncmp(buf, "Uid:", 4)) {
-                       sscanf((buf + 5), "%d%d%d%d", (int *)&ruid,
-                               (int *)&euid, (int *)&suid, (int *)&fsuid);
-                       cgroup_dbg("Scanned proc values are %d %d %d %d\n",
-                               ruid, euid, suid, fsuid);
-                       fclose(fp);
-                       return euid;
-               }
-       }
-       fclose(fp);
-
-       /* If we are here, we could not find euid. Return error. */
-       return -1;
-}
-
-/*
- * Go through /proc/<pid>/status file to determine the egid of the
- * process.
- * It returns 0 on success and negative values on failure.
- */
-
-int egid_of_pid(pid_t pid)
-{
-       FILE *fp;
-       char path[FILENAME_MAX];
-       char buf[TEMP_BUF];
-       gid_t rgid, egid, sgid, fsgid;
-
-       sprintf(path, "/proc/%d/status", pid);
-       fp = fopen(path, "r");
-       if (!fp) {
-               cgroup_dbg("Error in opening file %s:%s\n", path,
-                               strerror(errno));
-               return -1;
-       }
-
-       while (fgets(buf, TEMP_BUF, fp)) {
-               if (!strncmp(buf, "Gid:", 4)) {
-                       sscanf((buf + 5), "%d%d%d%d", (int *)&rgid,
-                               (int *)&egid, (int *)&sgid, (int *)&fsgid);
-                       cgroup_dbg("Scanned proc values are %d %d %d %d\n",
-                               rgid, egid, sgid, fsgid);
-                       fclose(fp);
-                       return egid;
-               }
-       }
-       fclose(fp);
-
-       /* If we are here, we could not find egid. Return error. */
-       return -1;
-}
-
 /*
  * Change process group as specified on command line.
  */
@@ -137,16 +64,8 @@ int change_group_uid_gid(pid_t pid)
        int ret;
 
        /* Put pid into right cgroup as per rules in /etc/cgrules.conf */
-       euid = euid_of_pid(pid);
-       if (euid == -1) {
-               fprintf(stderr, "Error in determining euid of"
-               " pid %d\n", pid);
-               return -1;
-       }
-
-       egid = egid_of_pid(pid);
-       if (egid == -1) {
-               fprintf(stderr, "Error in determining egid of"
+       if (cgroup_get_uid_gid_from_procfs(pid, &euid, &egid)) {
+               fprintf(stderr, "Error in determining euid/egid of"
                " pid %d\n", pid);
                return -1;
        }