~ubuntu-branches/ubuntu/utopic/ubuntu-app-launch/utopic

« back to all changes in this revision

Viewing changes to helpers-shared.c

  • Committer: Package Import Robot
  • Author(s): Łukasz 'sil2100' Zemczak
  • Date: 2014-08-19 09:52:33 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20140819095233-5mvkp2nderj92rww
Tags: 0.4+14.10.20140808.3.is.0.4+14.10.20140605.3-0ubuntu1
Temporarily revert the cgroup support introduced in the last
version, as it was causing regressions in our test infrastructure

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2013 Canonical Ltd.
3
 
 *
4
 
 * This program is free software: you can redistribute it and/or modify it
5
 
 * under the terms of the GNU General Public License version 3, as published
6
 
 * by the Free Software Foundation.
7
 
 *
8
 
 * This program is distributed in the hope that it will be useful, but
9
 
 * WITHOUT ANY WARRANTY; without even the implied warranties of
10
 
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11
 
 * PURPOSE.  See the GNU General Public License for more details.
12
 
 *
13
 
 * You should have received a copy of the GNU General Public License along
14
 
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 
 *
16
 
 * Authors:
17
 
 *     Ted Gould <ted.gould@canonical.com>
18
 
 */
19
 
 
20
 
#include "helpers.h"
21
 
#include <gio/gio.h>
22
 
#include <cgmanager/cgmanager.h>
23
 
 
24
 
/* Check to make sure we have the sections and keys we want */
25
 
static gboolean
26
 
verify_keyfile (GKeyFile * inkeyfile, const gchar * desktop)
27
 
{
28
 
        if (inkeyfile == NULL) return FALSE;
29
 
 
30
 
        if (!g_key_file_has_group(inkeyfile, "Desktop Entry")) {
31
 
                g_warning("Desktop file '%s' is missing the 'Desktop Entry' group", desktop);
32
 
                return FALSE;
33
 
        }
34
 
 
35
 
        if (!g_key_file_has_key(inkeyfile, "Desktop Entry", "Exec", NULL)) {
36
 
                g_warning("Desktop file '%s' is missing the 'Exec' key", desktop);
37
 
                return FALSE;
38
 
        }
39
 
 
40
 
        return TRUE;
41
 
}
42
 
 
43
 
/* Try to find a desktop file in a particular data directory */
44
 
static GKeyFile *
45
 
try_dir (const char * dir, const gchar * desktop)
46
 
{
47
 
        gchar * fullpath = g_build_filename(dir, "applications", desktop, NULL);
48
 
        GKeyFile * keyfile = g_key_file_new();
49
 
 
50
 
        /* NOTE: Leaving off the error here as we'll get a bunch of them,
51
 
           so individuals aren't really useful */
52
 
        gboolean loaded = g_key_file_load_from_file(keyfile, fullpath, G_KEY_FILE_NONE, NULL);
53
 
 
54
 
        g_free(fullpath);
55
 
 
56
 
        if (!loaded) {
57
 
                g_key_file_free(keyfile);
58
 
                return NULL;
59
 
        }
60
 
 
61
 
        if (!verify_keyfile(keyfile, desktop)) {
62
 
                g_key_file_free(keyfile);
63
 
                return NULL;
64
 
        }
65
 
 
66
 
        return keyfile;
67
 
}
68
 
 
69
 
/* Find the keyfile that we need for a particular AppID and return it.
70
 
   Or NULL if we can't find it. */
71
 
GKeyFile *
72
 
keyfile_for_appid (const gchar * appid, gchar ** desktopfile)
73
 
{
74
 
        gchar * desktop = g_strdup_printf("%s.desktop", appid);
75
 
 
76
 
        const char * const * data_dirs = g_get_system_data_dirs();
77
 
        GKeyFile * keyfile = NULL;
78
 
        int i;
79
 
 
80
 
        keyfile = try_dir(g_get_user_data_dir(), desktop);
81
 
        if (keyfile != NULL && desktopfile != NULL && *desktopfile == NULL) {
82
 
                *desktopfile = g_build_filename(g_get_user_data_dir(), "applications", desktop, NULL);
83
 
        }
84
 
 
85
 
        for (i = 0; data_dirs[i] != NULL && keyfile == NULL; i++) {
86
 
                keyfile = try_dir(data_dirs[i], desktop);
87
 
 
88
 
                if (keyfile != NULL && desktopfile != NULL && *desktopfile == NULL) {
89
 
                        *desktopfile = g_build_filename(data_dirs[i], "applications", desktop, NULL);
90
 
                }
91
 
        }
92
 
 
93
 
        g_free(desktop);
94
 
 
95
 
        return keyfile;
96
 
}
97
 
 
98
 
/* Get the connection to the cgroup manager */
99
 
GDBusConnection *
100
 
cgroup_manager_connection (void)
101
 
{
102
 
        GError * error = NULL;
103
 
 
104
 
        GDBusConnection * cgmanager = NULL;
105
 
 
106
 
        if (g_getenv("UBUNTU_APP_LAUNCH_CG_MANAGER_SESSION_BUS")) {
107
 
                /* For working dbusmock */
108
 
                g_debug("Connecting to CG Manager on session bus");
109
 
                cgmanager = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
110
 
        } else {
111
 
                cgmanager = g_dbus_connection_new_for_address_sync(
112
 
                        CGMANAGER_DBUS_PATH,
113
 
                        G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
114
 
                        NULL, /* Auth Observer */
115
 
                        NULL, /* Cancellable */
116
 
                        &error);
117
 
        }
118
 
 
119
 
        if (error != NULL) {
120
 
                g_warning("Unable to connect to cgroup manager: %s", error->message);
121
 
                g_error_free(error);
122
 
                return NULL;
123
 
        }
124
 
 
125
 
        return cgmanager;
126
 
}
127
 
 
128
 
/* Get the PIDs for a particular cgroup */
129
 
/* We're using the base cgroup 'freezer' in this code (and
130
 
   in the Upstart jobs). Really the actual group is meaningless
131
 
   we just need one that is in every kernel we need to support.
132
 
   We're just using the cgroup as a bag of PIDs, not for
133
 
   restricting any particular resource. */
134
 
GList *
135
 
pids_from_cgroup (GDBusConnection * cgmanager, const gchar * jobname, const gchar * instancename)
136
 
{
137
 
        GError * error = NULL;
138
 
        const gchar * name = g_getenv("UBUNTU_APP_LAUNCH_CG_MANAGER_NAME");
139
 
        gchar * groupname = NULL;
140
 
        if (jobname != NULL) {
141
 
                groupname = g_strdup_printf("upstart/%s-%s", jobname, instancename);
142
 
        }
143
 
 
144
 
        g_debug("Looking for cg manager '%s' group '%s'", name, groupname);
145
 
 
146
 
        GVariant * vtpids = g_dbus_connection_call_sync(cgmanager,
147
 
                name, /* bus name for direct connection is NULL */
148
 
                "/org/linuxcontainers/cgmanager",
149
 
                "org.linuxcontainers.cgmanager0_0",
150
 
                "GetTasks",
151
 
                g_variant_new("(ss)", "freezer", groupname ? groupname : ""),
152
 
                G_VARIANT_TYPE("(ai)"),
153
 
                G_DBUS_CALL_FLAGS_NONE,
154
 
                -1, /* default timeout */
155
 
                NULL, /* cancellable */
156
 
                &error);
157
 
 
158
 
        g_free(groupname);
159
 
 
160
 
        if (error != NULL) {
161
 
                g_warning("Unable to get PID list from cgroup manager: %s", error->message);
162
 
                g_error_free(error);
163
 
                return NULL;
164
 
        }
165
 
 
166
 
        GVariant * vpids = g_variant_get_child_value(vtpids, 0);
167
 
        GVariantIter iter;
168
 
        g_variant_iter_init(&iter, vpids);
169
 
        gint32 pid;
170
 
        GList * retval = NULL;
171
 
 
172
 
        while (g_variant_iter_loop(&iter, "i", &pid)) {
173
 
                retval = g_list_prepend(retval, GINT_TO_POINTER(pid));
174
 
        }
175
 
 
176
 
        g_variant_unref(vpids);
177
 
        g_variant_unref(vtpids);
178
 
 
179
 
        return retval;
180
 
}