~upstart-devel/upstart/trunk

« back to all changes in this revision

Viewing changes to init/cgroup.c

  • Committer: James Hunt
  • Date: 2014-09-03 16:28:24 UTC
  • mfrom: (1660.1.1 upstart-bug-1357252)
  • Revision ID: james.hunt@ubuntu.com-20140903162824-4f039oykmggh18kh
* Merge of lp:~jamesodhunt/upstart/bug-1357252.

Show diffs side-by-side

added added

removed removed

Lines of Context:
302
302
}
303
303
 
304
304
/**
 
305
 * cgroup_clear:
 
306
 *
 
307
 * @cgroups: list of CGroup objects,
 
308
 *
 
309
 * Remove all cgroups associated with this job.
 
310
 *
 
311
 * Should be called by the _last_ job process to avoid racing with the
 
312
 * cgroup manager which may remove an empty cgroup before the latest job
 
313
 * process (which needs the cgroup) has been spawned.
 
314
 *
 
315
 * Returns: TRUE on success, FALSE on raised error.
 
316
 **/
 
317
int
 
318
cgroup_clear (NihList *cgroups)
 
319
{
 
320
        nih_assert (cgroups);
 
321
        nih_assert (cgroup_manager);
 
322
 
 
323
        if (! cgroup_support_enabled ())
 
324
                return TRUE;
 
325
 
 
326
        if (NIH_LIST_EMPTY (cgroups))
 
327
                return TRUE;
 
328
 
 
329
        NIH_LIST_FOREACH (cgroups, iter) {
 
330
                CGroup *cgroup = (CGroup *)iter;
 
331
 
 
332
                NIH_LIST_FOREACH (&cgroup->names, iter2) {
 
333
                        CGroupName   *cgname = (CGroupName *)iter2;
 
334
                        char         *cgpath;
 
335
                        int           ret;
 
336
 
 
337
                        cgpath = cgname->expanded ? cgname->expanded : cgname->name;
 
338
 
 
339
                        /* Get the cgroup manager to delete the cgroup once no more job
 
340
                         * processes remain in it.
 
341
                         */
 
342
                        ret = cgmanager_remove_on_empty_sync (NULL,
 
343
                                        cgroup_manager,
 
344
                                        cgroup->controller,
 
345
                                        cgpath);
 
346
 
 
347
                        if (ret < 0) 
 
348
                                return FALSE;
 
349
                }
 
350
        }
 
351
 
 
352
        return TRUE;
 
353
}
 
354
 
 
355
/**
305
356
 * cgroup_setup:
306
357
 *
307
358
 * @cgroups: list of CGroup objects,
316
367
 * Returns: TRUE on success, FALSE on raised error.
317
368
 **/
318
369
int
319
 
cgroup_setup (NihList *cgroups, char * const *env, uid_t uid, gid_t gid)
 
370
cgroup_setup (NihList       *cgroups,
 
371
              char * const  *env,
 
372
              uid_t          uid,
 
373
              gid_t          gid)
320
374
{
321
375
        const char       *upstart_job = NULL;
322
376
        const char       *upstart_instance = NULL;
1004
1058
        /* Drop initial reference now the proxy holds one */
1005
1059
        dbus_connection_unref (connection);
1006
1060
 
1007
 
        nih_debug ("Connected to cgroup manager");
1008
 
 
1009
1061
        return 0;
1010
1062
}
1011
1063
 
1021
1073
        nih_assert (connection);
1022
1074
        nih_assert (cgroup_manager_address);
1023
1075
 
1024
 
        nih_warn (_("Disconnected from cgroup manager"));
1025
 
 
1026
1076
        cgroup_manager = NULL;
1027
1077
        nih_free (cgroup_manager_address);
1028
1078
        cgroup_manager_address = NULL;
1075
1125
                                                   UPSTART_CGROUP_ROOT,
1076
1126
                                                   pid);
1077
1127
 
1078
 
 
1079
1128
                if (ret < 0)
1080
1129
                        return FALSE;
1081
 
 
1082
 
                nih_debug ("Moved pid %d to root of '%s' controller cgroup",
1083
 
                           pid, controller);
1084
1130
        }
1085
1131
 
1086
 
        /* Ask cgmanager to create the cgroup */
 
1132
        /* Ask the cgroup manager to create the cgroup */
1087
1133
        ret = cgmanager_create_sync (NULL,
1088
1134
                        cgroup_manager,
1089
1135
                        controller,
1093
1139
        if (ret < 0)
1094
1140
                return FALSE;
1095
1141
 
1096
 
        nih_debug ("%s '%s' controller cgroup '%s'",
1097
 
                        ! existed ? "Created" : "Using existing",
1098
 
                        controller, path);
1099
 
 
1100
 
        /* Get the cgroup manager to delete the cgroup once no more job
1101
 
         * processes remain in it. Never mind if auto-deletion occurs between
1102
 
         * a jobs processes since the group will be recreated anyway by
1103
 
         * cgroup_create().
1104
 
         *
1105
 
         * This may seem incorrect since if we create the group,
1106
 
         * then mark it to be auto-removed when empty, surely
1107
 
         * it will be immediately deleted? However, the way this works
1108
 
         * is that the group will be deleted once it has _become_ empty
1109
 
         * (having at some time *not* been empty).
1110
 
         *
1111
 
         * The logic of using auto-delete is slightly inefficient
1112
 
         * in terms of cgmanager usage, but is hugely beneficial to
1113
 
         * Upstart since it avoids having to store details of which
1114
 
         * groups were created by jobs and also avoids the complexity of
1115
 
         * the child (which is responsible for creating the cgroups)
1116
 
         * pass back these details asynchronously to the parent to avoid
1117
 
         * it blocking.
1118
 
         */
1119
 
        ret = cgmanager_remove_on_empty_sync (NULL,
1120
 
                        cgroup_manager,
1121
 
                        controller,
1122
 
                        path);
1123
 
 
1124
 
        if (ret < 0)
1125
 
                return FALSE;
1126
 
 
1127
 
        nih_debug ("Set remove on empty for '%s' controller cgroup '%s'",
1128
 
                        controller, path);
1129
 
 
1130
1142
        return TRUE;
1131
1143
}
1132
1144
 
1162
1174
        if (ret < 0)
1163
1175
                return FALSE;
1164
1176
 
1165
 
        nih_debug ("Moved pid %d to '%s' controller cgroup '%s'",
1166
 
                        pid, controller, path);
1167
 
 
1168
1177
        return TRUE;
1169
1178
}
1170
1179
 
1371
1380
                        return FALSE;
1372
1381
        }
1373
1382
 
1374
 
        nih_debug ("Applied cgroup settings to '%s' controller cgroup '%s'",
1375
 
                        controller, path);
1376
 
 
1377
1383
        return TRUE;
1378
1384
}
1379
1385
 
1455
1461
        if (ret < 0)
1456
1462
                return FALSE;
1457
1463
 
1458
 
        nih_debug ("Changed ownership of '%s' controller cgroup '%s'",
1459
 
                        controller, path);
1460
 
 
1461
1464
        return TRUE;
1462
1465
}