コード例 #1
0
ファイル: cfgdb.c プロジェクト: adeason/openafs
/*
 * UpdateWorkerThread() -- thread for updating CellServDB of servers in
 *     a single name block.
 */
static void *
UpdateWorkerThread(void *argp)
{
    afs_status_t sync_tst = 0;
    cfg_csdb_update_name_t *nameBlockp = (cfg_csdb_update_name_t *) argp;
    int opDisposition;

    /* Pthread mutex and condition variable functions should never fail,
     * but if they do make a best effort attempt to report the problem;
     * will not be able to avoid race conditions in the face of such failures.
     */

    if (pthread_mutex_lock(&nameBlockp->ctrl->mutex)) {
	sync_tst = ADMMUTEXLOCK;
    }

    while ((opDisposition = nameBlockp->ctrl->disposition) == CSDB_WAIT) {
	/* wait for start/abort signal */
	if (pthread_cond_wait
	    (&nameBlockp->ctrl->event, &nameBlockp->ctrl->mutex)) {
	    /* avoid tight loop if condition variable wait fails */
	    cfgutil_Sleep(1);
	}
    }

    if (pthread_mutex_unlock(&nameBlockp->ctrl->mutex)) {
	sync_tst = ADMMUTEXUNLOCK;
    }

    if (opDisposition == CSDB_GO) {
	/* proceed with CellServDB update */
	int i;

	for (i = 0; i < nameBlockp->serverCount; i++) {
	    cfg_cellServDbStatus_t *statusp;

	    /* alloc memory for status information (including host name) */

	    while ((statusp = (cfg_cellServDbStatus_t *)
		    malloc(sizeof(*statusp) + AFS_MAX_SERVER_NAME_LEN)) ==
		   NULL) {
		/* avoid tight loop while waiting for status storage */
		cfgutil_Sleep(1);
	    }

	    statusp->fsDbHost = ((char *)statusp + sizeof(*statusp));

	    /* make update and set status information */

	    strcpy(statusp->fsDbHost, nameBlockp->serverName[i]);

	    if (sync_tst != 0) {
		/* report pthread problem */
		statusp->status = sync_tst;
	    } else {
		/* attempt update and report update status */
		void *bosHandle;
		afs_status_t tst2, tst = 0;

		if (!bos_ServerOpen
		    (nameBlockp->ctrl->cfg_host->cellHandle,
		     nameBlockp->serverName[i], &bosHandle, &tst2)) {
		    tst = tst2;

		} else {
		    char *opHost = nameBlockp->ctrl->opHostAlias;

		    if (nameBlockp->ctrl->op == CSDB_OP_ADD) {
			if (!bos_HostCreate(bosHandle, opHost, &tst2)) {
			    tst = tst2;
			}
		    } else {
			if (!bos_HostDelete(bosHandle, opHost, &tst2)) {
			    if (tst2 != BZNOENT) {
				tst = tst2;
			    }
			}
		    }

		    if (!bos_ServerClose(bosHandle, &tst2)) {
			tst = tst2;
		    }
		}
		statusp->status = tst;
	    }

	    /* make call back to return update status */

	    (*nameBlockp->ctrl->callBack) (nameBlockp->ctrl->callBackId,
					   statusp, 0);
	}
    }

    /* last worker makes termination call back and deallocates control block */

    if (pthread_mutex_lock(&nameBlockp->ctrl->mutex)) {
	sync_tst = ADMMUTEXLOCK;
    }

    nameBlockp->ctrl->workersActive--;

    if (nameBlockp->ctrl->workersActive == 0) {
	if (opDisposition == CSDB_GO) {
	    (*nameBlockp->ctrl->callBack) (nameBlockp->ctrl->callBackId, NULL,
					   sync_tst);
	}
	free(nameBlockp->ctrl);
    }

    if (pthread_mutex_unlock(&nameBlockp->ctrl->mutex)) {
	sync_tst = ADMMUTEXUNLOCK;
    }

    /* all workers deallocate their own name block */
    free(nameBlockp);

    return NULL;
}
コード例 #2
0
/*
 * cfgutil_WindowsServiceStop() -- Stop a Windows service on local host.
 *
 *     The value of timeout specifies the maximum time, in seconds, to wait
 *     for the service to be in the SERVICE_STOPPED state.
 *
 *     If service was already stopped/stopping then *wasStopped is true (1).
 *
 * RETURN CODES: 1 success, 0 failure (st indicates why)
 */
int
cfgutil_WindowsServiceStop(LPCTSTR svcName, unsigned timeout,
                           short *wasStopped, afs_status_p st)
{
    int rc = 1;
    afs_status_t tst = 0;
    SC_HANDLE scmHandle, svcHandle;
    DWORD svcAccess = (SERVICE_STOP | SERVICE_QUERY_STATUS);

    *wasStopped = 0;

    if ((scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL
            || (svcHandle = OpenService(scmHandle, svcName, svcAccess)) == NULL) {
        /* can't connect to SCM or can't open service */
        DWORD status = GetLastError();

        if (status == ERROR_ACCESS_DENIED) {
            tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_NOPRIV);
        } else if (status == ERROR_SERVICE_DOES_NOT_EXIST) {
            tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_BAD);
        } else {
            tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_STATUSUNK);
        }

        if (scmHandle != NULL) {
            CloseServiceHandle(scmHandle);
        }

    } else {
        /* service configured; attempt to stop */
        SERVICE_STATUS svcStatus;

        if (!ControlService(svcHandle, SERVICE_CONTROL_STOP, &svcStatus)) {
            /* service stop failed */
            DWORD status = GetLastError();

            if (status == ERROR_SERVICE_NOT_ACTIVE) {
                *wasStopped = 1;
            } else {
                if (status == ERROR_ACCESS_DENIED) {
                    tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_NOPRIV);
                } else if (status == ERROR_INVALID_SERVICE_CONTROL
                           || status == ERROR_SERVICE_CANNOT_ACCEPT_CTRL
                           || status == ERROR_SERVICE_REQUEST_TIMEOUT) {
                    tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_NOTREADY);
                } else {
                    tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_BAD);
                }
            }
        }

        /* wait for service to be in SERVICE_STOPPED state */
        if (tst == 0 && timeout > 0) {
            time_t timeStart = time(NULL);

            while (1) {
                if (!QueryServiceStatus(svcHandle, &svcStatus)) {
                    tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_STATUSUNK);
                    break;
                } else if (svcStatus.dwCurrentState == SERVICE_STOPPED) {
                    break;
                } else if (difftime(time(NULL), timeStart) > timeout) {
                    tst = ServiceCodeXlate(svcName, CFGUTIL_SVC_TIMEOUT);
                    break;
                } else {
                    /* sleep a bit and check state again */
                    cfgutil_Sleep(5);
                }
            }

            if (tst == 0) {
                /* wait just a bit more because we're paranoid */
                cfgutil_Sleep(1);
            }
        }

        CloseServiceHandle(svcHandle);
        CloseServiceHandle(scmHandle);
    }

    if (tst != 0) {
        /* indicate failure */
        rc = 0;
    }
    if (st != NULL) {
        *st = tst;
    }
    return rc;
}