[launchd-changes] [23009] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jan 11 16:33:20 PST 2007
Revision: 23009
http://trac.macosforge.org/projects/launchd/changeset/23009
Author: zarzycki at apple.com
Date: 2007-01-11 16:33:20 -0800 (Thu, 11 Jan 2007)
Log Message:
-----------
<rdar://problem/4911067> KeepAlive with PathState should monitor for file creation state change
Modified Paths:
--------------
trunk/launchd/src/launchd.c
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/launchd_core_logic.h
Modified: trunk/launchd/src/launchd.c
===================================================================
--- trunk/launchd/src/launchd.c 2007-01-10 21:58:22 UTC (rev 23008)
+++ trunk/launchd/src/launchd.c 2007-01-12 00:33:20 UTC (rev 23009)
@@ -645,7 +645,7 @@
if (new_networking_state != network_up) {
network_up = new_networking_state;
- jobmgr_dispatch_all_other_semaphores(root_jobmgr, NULL);
+ jobmgr_dispatch_all_semaphores(root_jobmgr);
}
}
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2007-01-10 21:58:22 UTC (rev 23008)
+++ trunk/launchd/src/launchd_core_logic.c 2007-01-12 00:33:20 UTC (rev 23009)
@@ -104,8 +104,10 @@
static void machservice_setup_options(launch_data_t obj, const char *key, void *context);
static void machservice_resetport(job_t j, struct machservice *ms);
static struct machservice *machservice_new(job_t j, const char *name, mach_port_t *serviceport);
+static void machservice_ignore(job_t j, struct machservice *ms);
+static void machservice_watch(job_t j, struct machservice *ms);
static void machservice_delete(struct machservice *);
-static void machservice_watch(struct machservice *);
+static void machservice_request_notifications(struct machservice *);
static mach_port_t machservice_port(struct machservice *);
static job_t machservice_job(struct machservice *);
static bool machservice_hidden(struct machservice *);
@@ -127,19 +129,6 @@
static void socketgroup_callback(job_t j, struct kevent *kev);
static void socketgroup_setup(launch_data_t obj, const char *key, void *context);
-struct watchpath {
- SLIST_ENTRY(watchpath) sle;
- int fd;
- unsigned int is_qdir:1, __junk:31;
- char name[0];
-};
-
-static bool watchpath_new(job_t j, const char *name, bool qdir);
-static void watchpath_delete(job_t j, struct watchpath *wp);
-static void watchpath_watch(job_t j, struct watchpath *wp);
-static void watchpath_ignore(job_t j, struct watchpath *wp);
-static void watchpath_callback(job_t j, struct kevent *kev);
-
struct calendarinterval {
SLIST_ENTRY(calendarinterval) sle;
struct tm when;
@@ -178,12 +167,15 @@
FAILED_EXIT,
PATH_EXISTS,
PATH_MISSING,
+ PATH_CHANGES,
+ DIR_NOT_EMPTY,
// FILESYSTEMTYPE_IS_MOUNTED, /* for nfsiod, but maybe others */
} semaphore_reason_t;
struct semaphoreitem {
SLIST_ENTRY(semaphoreitem) sle;
semaphore_reason_t why;
+ int fd;
char what[0];
};
@@ -191,6 +183,9 @@
static void semaphoreitem_delete(job_t j, struct semaphoreitem *si);
static void semaphoreitem_setup(launch_data_t obj, const char *key, void *context);
static void semaphoreitem_setup_paths(launch_data_t obj, const char *key, void *context);
+static void semaphoreitem_callback(job_t j, struct kevent *kev);
+static void semaphoreitem_watch(job_t j, struct semaphoreitem *si);
+static void semaphoreitem_ignore(job_t j, struct semaphoreitem *si);
struct jobmgr_s {
SLIST_ENTRY(jobmgr_s) sle;
@@ -231,7 +226,6 @@
kq_callback kqjob_callback;
SLIST_ENTRY(job_s) sle;
SLIST_HEAD(, socketgroup) sockets;
- SLIST_HEAD(, watchpath) vnodes;
SLIST_HEAD(, calendarinterval) cal_intervals;
SLIST_HEAD(, envitem) global_env;
SLIST_HEAD(, envitem) env;
@@ -356,9 +350,9 @@
void
job_ignore(job_t j)
{
+ struct semaphoreitem *si;
struct socketgroup *sg;
struct machservice *ms;
- struct watchpath *wp;
if (j->currently_ignored) {
return;
@@ -370,12 +364,12 @@
socketgroup_ignore(j, sg);
}
- SLIST_FOREACH(wp, &j->vnodes, sle) {
- watchpath_ignore(j, wp);
+ SLIST_FOREACH(ms, &j->machservices, sle) {
+ machservice_ignore(j, ms);
}
- SLIST_FOREACH(ms, &j->machservices, sle) {
- job_assumes(j, runtime_remove_mport(ms->port) == KERN_SUCCESS);
+ SLIST_FOREACH(si, &j->semaphores, sle) {
+ semaphoreitem_ignore(j, si);
}
}
@@ -385,7 +379,6 @@
struct semaphoreitem *si;
struct socketgroup *sg;
struct machservice *ms;
- struct watchpath *wp;
if (!j->currently_ignored) {
return;
@@ -397,19 +390,12 @@
socketgroup_watch(j, sg);
}
- SLIST_FOREACH(wp, &j->vnodes, sle) {
- watchpath_watch(j, wp);
- }
-
SLIST_FOREACH(ms, &j->machservices, sle) {
- job_assumes(j, runtime_add_mport(ms->port, NULL, 0) == KERN_SUCCESS);
+ machservice_watch(j, ms);
}
SLIST_FOREACH(si, &j->semaphores, sle) {
- if (si->why == PATH_EXISTS || si->why == PATH_MISSING) {
- /* Maybe another job has the inverse path based semaphore as this job */
- jobmgr_dispatch_all_other_semaphores(root_jobmgr, j);
- }
+ semaphoreitem_watch(j, si);
}
}
@@ -583,7 +569,6 @@
{
struct calendarinterval *ci;
struct socketgroup *sg;
- struct watchpath *wp;
struct limititem *li;
struct envitem *ei;
struct machservice *ms;
@@ -627,9 +612,6 @@
while ((sg = SLIST_FIRST(&j->sockets))) {
socketgroup_delete(j, sg);
}
- while ((wp = SLIST_FIRST(&j->vnodes))) {
- watchpath_delete(j, wp);
- }
while ((ci = SLIST_FIRST(&j->cal_intervals))) {
calendarinterval_delete(j, ci);
}
@@ -1299,9 +1281,6 @@
void
job_import_array(job_t j, const char *key, launch_data_t value)
{
- bool is_q_dir = false;
- bool is_wp = false;
-
switch (key[0]) {
case 'l':
case 'L':
@@ -1314,14 +1293,24 @@
case 'q':
case 'Q':
if (strcasecmp(key, LAUNCH_JOBKEY_QUEUEDIRECTORIES) == 0) {
- is_q_dir = true;
- is_wp = true;
+ size_t i, qd_cnt = launch_data_array_get_count(value);
+ const char *thepath;
+ for (i = 0; i < qd_cnt; i++) {
+ thepath = launch_data_get_string(launch_data_array_get_index(value, i));
+ semaphoreitem_new(j, DIR_NOT_EMPTY, thepath);
+ }
+
}
break;
case 'w':
case 'W':
if (strcasecmp(key, LAUNCH_JOBKEY_WATCHPATHS) == 0) {
- is_wp = true;
+ size_t i, wp_cnt = launch_data_array_get_count(value);
+ const char *thepath;
+ for (i = 0; i < wp_cnt; i++) {
+ thepath = launch_data_get_string(launch_data_array_get_index(value, i));
+ semaphoreitem_new(j, PATH_CHANGES, thepath);
+ }
}
break;
case 'b':
@@ -1341,15 +1330,6 @@
default:
break;
}
-
- if (is_wp) {
- size_t i, wp_cnt = launch_data_array_get_count(value);
- const char *thepath;
- for (i = 0; i < wp_cnt; i++) {
- thepath = launch_data_get_string(launch_data_array_get_index(value, i));
- watchpath_new(j, thepath, is_q_dir);
- }
- }
}
void
@@ -1752,7 +1732,7 @@
}
break;
case EVFILT_VNODE:
- watchpath_callback(j, kev);
+ semaphoreitem_callback(j, kev);
break;
case EVFILT_READ:
if (kev->ident == (uintptr_t)j->log_redirect_fd) {
@@ -2365,111 +2345,82 @@
}
}
-bool
-watchpath_new(job_t j, const char *name, bool qdir)
-{
- struct watchpath *wp = calloc(1, sizeof(struct watchpath) + strlen(name) + 1);
-
- if (!job_assumes(j, wp != NULL)) {
- return false;
- }
-
- wp->is_qdir = qdir;
-
- wp->fd = -1; /* watchpath_watch() will open this */
-
- strcpy(wp->name, name);
-
- SLIST_INSERT_HEAD(&j->vnodes, wp, sle);
-
- return true;
-}
-
-void
-watchpath_delete(job_t j, struct watchpath *wp)
-{
- if (wp->fd != -1) {
- job_assumes(j, close(wp->fd) != -1);
- }
-
- SLIST_REMOVE(&j->vnodes, wp, watchpath, sle);
-
- free(wp);
-}
-
void
-watchpath_ignore(job_t j, struct watchpath *wp)
+semaphoreitem_ignore(job_t j, struct semaphoreitem *si)
{
- if (wp->fd != -1) {
- job_log(j, LOG_DEBUG, "Ignoring Vnode: %d", wp->fd);
- job_assumes(j, kevent_mod(wp->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1);
+ if (si->fd != -1) {
+ job_log(j, LOG_DEBUG, "Ignoring Vnode: %d", si->fd);
+ job_assumes(j, kevent_mod(si->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL) != -1);
}
}
void
-watchpath_watch(job_t j, struct watchpath *wp)
+semaphoreitem_watch(job_t j, struct semaphoreitem *si)
{
- int fflags = NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK;
- int qdir_file_cnt;
-
- if (!wp->is_qdir) {
- fflags |= NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE;
+ char parentdir_path[PATH_MAX], *which_path = si->what;
+ int fflags = 0;
+
+ switch (si->why) {
+ case PATH_EXISTS:
+ fflags = NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_EXTEND|NOTE_WRITE;
+ strlcpy(parentdir_path, dirname(si->what), sizeof(parentdir_path));
+ which_path = parentdir_path;
+ break;
+ case PATH_MISSING:
+ fflags = NOTE_DELETE|NOTE_RENAME;
+ break;
+ case PATH_CHANGES:
+ fflags = NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE|NOTE_EXTEND|NOTE_WRITE|NOTE_ATTRIB|NOTE_LINK;
+ break;
+ default:
+ return;
}
- if (wp->fd == -1) {
- wp->fd = _fd(open(wp->name, O_EVTONLY|O_NOCTTY|O_NOFOLLOW));
+ if (si->fd == -1) {
+ si->fd = _fd(open(which_path, O_EVTONLY|O_NOCTTY));
}
- if (wp->fd == -1) {
- return job_log_error(j, LOG_ERR, "Watchpath monitoring failed on \"%s\"", wp->name);
+ if (si->fd == -1) {
+ return job_log_error(j, LOG_ERR, "Watchpath monitoring failed on \"%s\"", which_path);
}
- job_log(j, LOG_DEBUG, "Watching Vnode: %d", wp->fd);
- job_assumes(j, kevent_mod(wp->fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, fflags, 0, j) != -1);
-
- if (!wp->is_qdir) {
- return;
- }
-
- if (-1 == (qdir_file_cnt = dir_has_files(j, wp->name))) {
- job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", wp->name);
- } else if (qdir_file_cnt > 0) {
- job_dispatch(j, true);
- }
+ job_log(j, LOG_DEBUG, "Watching Vnode: %d", si->fd);
+ job_assumes(j, kevent_mod(si->fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, fflags, 0, j) != -1);
}
void
-watchpath_callback(job_t j, struct kevent *kev)
+semaphoreitem_callback(job_t j, struct kevent *kev)
{
- struct watchpath *wp;
- int dir_file_cnt;
+ struct semaphoreitem *si;
- SLIST_FOREACH(wp, &j->vnodes, sle) {
- if (wp->fd == (int)kev->ident) {
+ SLIST_FOREACH(si, &j->semaphores, sle) {
+ switch (si->why) {
+ case PATH_CHANGES:
+ case PATH_EXISTS:
+ case PATH_MISSING:
break;
+ default:
+ continue;
}
+
+ if (si->fd == (int)kev->ident) {
+ break;
+ }
}
- job_assumes(j, wp != NULL);
+ if (!job_assumes(j, si != NULL)) {
+ return;
+ }
if ((NOTE_DELETE|NOTE_RENAME|NOTE_REVOKE) & kev->fflags) {
- job_log(j, LOG_DEBUG, "Path invalidated: %s", wp->name);
- job_assumes(j, close(wp->fd) == 0);
- wp->fd = -1; /* this will get fixed in watchpath_watch() */
- } else if (!wp->is_qdir) {
- job_log(j, LOG_DEBUG, "Watch path modified: %s", wp->name);
- } else {
- job_log(j, LOG_DEBUG, "Queue directory modified: %s", wp->name);
-
- if (-1 == (dir_file_cnt = dir_has_files(j, wp->name))) {
- job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", wp->name);
- } else if (0 == dir_file_cnt) {
- job_log(j, LOG_DEBUG, "Spurious wake up, directory is empty again: %s", wp->name);
- return;
- }
+ job_log(j, LOG_DEBUG, "Path invalidated: %s", si->what);
+ job_assumes(j, close(si->fd) == 0);
+ si->fd = -1; /* this will get fixed in semaphoreitem_watch() */
}
- job_dispatch(j, true);
+ job_log(j, LOG_DEBUG, "Watch path modified: %s", si->what);
+
+ job_dispatch(j, si->why == PATH_CHANGES ? true : false);
}
bool
@@ -2818,6 +2769,8 @@
SLIST_FOREACH(si, &j->semaphores, sle) {
bool wanted_state = false;
+ int qdir_file_cnt;
+
switch (si->why) {
case NETWORK_UP:
wanted_state = true;
@@ -2843,9 +2796,22 @@
if ((bool)(stat(si->what, &sb) == 0) == wanted_state) {
job_log(j, LOG_DEBUG, "KeepAlive check: job configured to run while the following path %s: %s",
wanted_state ? "exists" : "is missing", si->what);
+ if (si->fd != -1) {
+ job_assumes(j, close(si->fd) == 0);
+ si->fd = -1;
+ }
return true;
}
break;
+ case PATH_CHANGES:
+ break;
+ case DIR_NOT_EMPTY:
+ if (-1 == (qdir_file_cnt = dir_has_files(j, si->what))) {
+ job_log_error(j, LOG_ERR, "dir_has_files(\"%s\", ...)", si->what);
+ } else if (qdir_file_cnt > 0) {
+ return true;
+ }
+ break;
}
}
@@ -2928,6 +2894,18 @@
}
void
+machservice_watch(job_t j, struct machservice *ms)
+{
+ job_assumes(j, runtime_add_mport(ms->port, NULL, 0) == KERN_SUCCESS);
+}
+
+void
+machservice_ignore(job_t j, struct machservice *ms)
+{
+ job_assumes(j, runtime_remove_mport(ms->port) == KERN_SUCCESS);
+}
+
+void
machservice_resetport(job_t j, struct machservice *ms)
{
job_assumes(j, launchd_mport_close_recv(ms->port) == KERN_SUCCESS);
@@ -3347,7 +3325,7 @@
}
void
-machservice_watch(struct machservice *ms)
+machservice_request_notifications(struct machservice *ms)
{
mach_msg_id_t which = MACH_NOTIFY_DEAD_NAME;
@@ -3521,6 +3499,7 @@
return false;
}
+ si->fd = -1;
si->why = why;
if (what) {
@@ -3533,11 +3512,15 @@
}
void
-semaphoreitem_delete(job_t j, struct semaphoreitem *ri)
+semaphoreitem_delete(job_t j, struct semaphoreitem *si)
{
- SLIST_REMOVE(&j->semaphores, ri, semaphoreitem, sle);
+ SLIST_REMOVE(&j->semaphores, si, semaphoreitem, sle);
- free(ri);
+ if (si->fd != -1) {
+ job_assumes(j, close(si->fd) != -1);
+ }
+
+ free(si);
}
void
@@ -3571,18 +3554,18 @@
}
void
-jobmgr_dispatch_all_other_semaphores(jobmgr_t jm, job_t nj)
+jobmgr_dispatch_all_semaphores(jobmgr_t jm)
{
jobmgr_t jmi;
job_t ji, jn;
SLIST_FOREACH(jmi, &jm->submgrs, sle) {
- jobmgr_dispatch_all_other_semaphores(jmi, nj);
+ jobmgr_dispatch_all_semaphores(jmi);
}
SLIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) {
- if (ji != nj && !SLIST_EMPTY(&ji->semaphores)) {
+ if (!SLIST_EMPTY(&ji->semaphores)) {
job_dispatch(ji, false);
}
}
@@ -3979,7 +3962,7 @@
return BOOTSTRAP_SERVICE_ACTIVE;
}
- machservice_watch(ms);
+ machservice_request_notifications(ms);
job_log(j, LOG_INFO, "Check-in of service: %s", servicename);
@@ -4034,7 +4017,7 @@
if (serviceport != MACH_PORT_NULL) {
if ((ms = machservice_new(j, servicename, &serviceport))) {
- machservice_watch(ms);
+ machservice_request_notifications(ms);
} else {
return BOOTSTRAP_NO_MEMORY;
}
@@ -4228,7 +4211,7 @@
struct machservice *ms;
if ((ms = machservice_new(jmr->anonj, l2l_names[l2l_i], &l2l_ports[l2l_i]))) {
- machservice_watch(ms);
+ machservice_request_notifications(ms);
}
}
Modified: trunk/launchd/src/launchd_core_logic.h
===================================================================
--- trunk/launchd/src/launchd_core_logic.h 2007-01-10 21:58:22 UTC (rev 23008)
+++ trunk/launchd/src/launchd_core_logic.h 2007-01-12 00:33:20 UTC (rev 23009)
@@ -33,7 +33,7 @@
void jobmgr_set_stderr(jobmgr_t jm, const char *what);
bool jobmgr_is_idle(jobmgr_t jm);
void jobmgr_remove_all_inactive(jobmgr_t jm);
-void jobmgr_dispatch_all_other_semaphores(jobmgr_t jm, job_t nj);
+void jobmgr_dispatch_all_semaphores(jobmgr_t jm);
job_t jobmgr_find(jobmgr_t jm, const char *label);
void jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port);
bool jobmgr_ack_port_destruction(jobmgr_t jm, mach_port_t p);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070111/0b605740/attachment.html
More information about the launchd-changes
mailing list