示例#1
0
storeIOState *
storeDiskdCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
    STIOCB * callback, void *callback_data)
{
    sfileno f;
    int x;
    storeIOState *sio;
    char *buf;
    int shm_offset;
    diskdinfo_t *diskdinfo = SD->fsdata;
    diskdstate_t *diskdstate;
    /*
     * Fail on open() if there are too many requests queued.
     */
    if (diskdinfo->away > diskdinfo->magic1) {
	diskd_stats.open_fail_queue_len++;
	return NULL;
    }
    /* Allocate a number */
    f = storeDiskdDirMapBitAllocate(SD);
    debug(79, 3) ("storeDiskdCreate: fileno %08X\n", f);

    CBDATA_INIT_TYPE_FREECB(storeIOState, storeDiskdIOFreeEntry);
    sio = cbdataAlloc(storeIOState);
    sio->fsstate = diskdstate = memPoolAlloc(diskd_state_pool);

    sio->swap_filen = f;
    sio->swap_dirn = SD->index;
    sio->mode = O_WRONLY | O_CREAT | O_TRUNC;
    sio->callback = callback;
    sio->callback_data = callback_data;
    sio->e = e;
    cbdataLock(callback_data);

    diskdstate->flags.writing = 0;
    diskdstate->flags.reading = 0;
    diskdstate->flags.close_request = 0;
    diskdstate->id = diskd_stats.sio_id++;

    buf = storeDiskdShmGet(SD, &shm_offset);
    xstrncpy(buf, storeDiskdDirFullPath(SD, f, NULL), SHMBUF_BLKSZ);
    x = storeDiskdSend(_MQD_OPEN,
	SD,
	diskdstate->id,
	sio,
	strlen(buf) + 1,
	sio->mode,
	shm_offset);
    if (x < 0) {
	debug(79, 1) ("storeDiskdSend OPEN: %s\n", xstrerror());
	storeDiskdShmPut(SD, shm_offset);
	cbdataUnlock(sio->callback_data);
	cbdataFree(sio);
	return NULL;
    }
    storeDiskdDirReplAdd(SD, e);
    diskd_stats.create.ops++;
    return sio;
}
示例#2
0
/* open for creating */
storeIOState *
storeAufsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data)
{
    char *path;
    storeIOState *sio;
    sfileno filn;
    sdirno dirn;
#if !ASYNC_CREATE
    int fd;
#endif

    /* Allocate a number */
    dirn = SD->index;
    filn = storeAufsDirMapBitAllocate(SD);
    path = storeAufsDirFullPath(SD, filn, NULL);

    debug(79, 3) ("storeAufsCreate: fileno %08X\n", filn);
    /*
     * we should detect some 'too many files open' condition and return
     * NULL here.
     */
#ifdef MAGIC2
    if (aioQueueSize() > MAGIC2)
	return NULL;
#endif
#if !ASYNC_CREATE
    fd = file_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
    if (fd < 0) {
	debug(79, 3) ("storeAufsCreate: got failure (%d)\n", errno);
	return NULL;
    }
#endif
    CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry);
    sio = cbdataAlloc(storeIOState);
    sio->fsstate = memPoolAlloc(squidaio_state_pool);
    ((squidaiostate_t *) (sio->fsstate))->fd = -1;
    ((squidaiostate_t *) (sio->fsstate))->flags.opening = 1;
    sio->swap_filen = filn;
    sio->swap_dirn = dirn;
    sio->mode = O_WRONLY | O_BINARY;
    sio->callback = callback;
    sio->callback_data = callback_data;
    sio->e = (StoreEntry *) e;
    cbdataLock(callback_data);
    Opening_FD++;
    statCounter.syscalls.disk.opens++;
#if ASYNC_CREATE
    aioOpen(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644, storeAufsOpenDone, sio, INDEX_OF_SD(SD));
#else
    storeAufsOpenDone(fd, sio, fd, 0);
#endif

    /* now insert into the replacement policy */
    storeAufsDirReplAdd(SD, e);
    return sio;

}
示例#3
0
/* open for reading */
storeIOState *
storeAufsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
    STIOCB * callback, void *callback_data)
{
    sfileno f = e->swap_filen;
    char *path = storeAufsDirFullPath(SD, f, NULL);
    storeIOState *sio;
#if !ASYNC_OPEN
    int fd;
#endif
    debug(79, 3) ("storeAufsOpen: fileno %08X\n", f);
    /*
     * we should detect some 'too many files open' condition and return
     * NULL here.
     */
#ifdef MAGIC2
#ifndef CC_FRAMEWORK
    if (aioQueueSize() > MAGIC2)
	return NULL;
#endif
#endif
#if !ASYNC_OPEN
    fd = file_open(path, O_RDONLY | O_BINARY | O_NOATIME);
    if (fd < 0) {
	debug(79, 3) ("storeAufsOpen: got failure (%d)\n", errno);
	return NULL;
    }
#endif
    CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry);
    sio = cbdataAlloc(storeIOState);
    sio->fsstate = memPoolAlloc(squidaio_state_pool);
    ((squidaiostate_t *) (sio->fsstate))->fd = -1;
    ((squidaiostate_t *) (sio->fsstate))->flags.opening = 1;
    sio->swap_filen = f;
    sio->swap_dirn = SD->index;
    sio->mode = O_RDONLY | O_BINARY;
    sio->callback = callback;
    sio->callback_data = callback_data;
    sio->e = e;
    cbdataLock(callback_data);
    Opening_FD++;
    statCounter.syscalls.disk.opens++;
#if ASYNC_OPEN
    aioOpen(path, O_RDONLY | O_BINARY | O_NOATIME, 0644, storeAufsOpenDone, sio, INDEX_OF_SD(SD));
#else
    storeAufsOpenDone(fd, sio, fd, 0);
#endif
    return sio;
}
示例#4
0
storeIOState *
storeUfsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data)
{
    storeIOState *sio;
    int fd;
    int mode = (O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
    char *path;
    ufsinfo_t *ufsinfo = (ufsinfo_t *) SD->fsdata;
    sfileno filn;
    sdirno dirn;

    /* Allocate a number */
    dirn = SD->index;
    filn = storeUfsDirMapBitAllocate(SD);
    ufsinfo->suggest = filn + 1;
    /* Shouldn't we handle a 'bitmap full' error here? */
    path = storeUfsDirFullPath(SD, filn, NULL);

    debug(79, 3) ("storeUfsCreate: fileno %08X\n", filn);
    fd = file_open(path, mode);
    if (fd < 0) {
	debug(79, 1) ("storeUfsCreate: Failed to create %s (%s)\n", path, xstrerror());
	return NULL;
    }
    debug(79, 3) ("storeUfsCreate: opened FD %d\n", fd);
    CBDATA_INIT_TYPE_FREECB(storeIOState, storeUfsIOFreeEntry);
    sio = cbdataAlloc(storeIOState);
    sio->fsstate = memPoolAlloc(ufs_state_pool);

    sio->swap_filen = filn;
    sio->swap_dirn = dirn;
    sio->mode = mode;
    sio->callback = callback;
    sio->callback_data = callback_data;
    cbdataLock(callback_data);
    sio->e = (StoreEntry *) e;
    ((ufsstate_t *) (sio->fsstate))->fd = fd;
    ((ufsstate_t *) (sio->fsstate))->flags.writing = 0;
    ((ufsstate_t *) (sio->fsstate))->flags.reading = 0;
    ((ufsstate_t *) (sio->fsstate))->flags.close_request = 0;
    store_open_disk_fd++;
    ufsinfo->open_files++;

    /* now insert into the replacement policy */
    storeUfsDirReplAdd(SD, e);
    return sio;
}
示例#5
0
static void
peerMonitorStart(peer * peer)
{
    PeerMonitor *pm;
    char *url = peer->monitor.url;
    if (!url || !*url)
	return;
    if (!peer->monitor.interval)
	return;
    CBDATA_INIT_TYPE_FREECB(PeerMonitor, freePeerMonitor);
    pm = cbdataAlloc(PeerMonitor);
    snprintf(pm->name, sizeof(pm->name), "monitor %s", peer->name);
    pm->peer = peer;
    peer->monitor.data = pm;
    cbdataLock(pm->peer);
    peerMonitorRequest(pm);
}
示例#6
0
storeIOState *
storeUfsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
    STIOCB * callback, void *callback_data)
{
    ufsinfo_t *ufsinfo = (ufsinfo_t *) SD->fsdata;
    sfileno f = e->swap_filen;
    char *path = storeUfsDirFullPath(SD, f, NULL);
    storeIOState *sio;
    struct stat sb;
    int fd;
    debug(79, 3) ("storeUfsOpen: fileno %08X\n", f);
    fd = file_open(path, O_RDONLY | O_BINARY | O_NOATIME);
    if (fd < 0) {
	debug(79, 3) ("storeUfsOpen: got failure (%d)\n", errno);
	return NULL;
    }
    debug(79, 3) ("storeUfsOpen: opened FD %d\n", fd);
    CBDATA_INIT_TYPE_FREECB(storeIOState, storeUfsIOFreeEntry);
    sio = cbdataAlloc(storeIOState);
    sio->fsstate = memPoolAlloc(ufs_state_pool);

    sio->swap_filen = f;
    sio->swap_dirn = SD->index;
    sio->mode = O_RDONLY | O_BINARY;
    sio->callback = callback;
    sio->callback_data = callback_data;
    cbdataLock(callback_data);
    sio->e = e;
    ((ufsstate_t *) (sio->fsstate))->fd = fd;
    ((ufsstate_t *) (sio->fsstate))->flags.writing = 0;
    ((ufsstate_t *) (sio->fsstate))->flags.reading = 0;
    ((ufsstate_t *) (sio->fsstate))->flags.close_request = 0;
    if (fstat(fd, &sb) == 0)
	sio->st_size = sb.st_size;
    store_open_disk_fd++;
    ufsinfo->open_files++;

    /* We should update the heap/dlink position here ! */
    return sio;
}
void
aclParseExternal(void *dataptr)
{
    external_acl_data **datap = dataptr;
    external_acl_data *data;
    char *token;
    if (*datap)
	self_destruct();
    CBDATA_INIT_TYPE_FREECB(external_acl_data, free_external_acl_data);
    data = cbdataAlloc(external_acl_data);
    token = strtok(NULL, w_space);
    if (!token)
	self_destruct();
    data->def = find_externalAclHelper(token);
    cbdataLock(data->def);
    if (!data->def)
	self_destruct();
    while ((token = strtokFile())) {
	wordlistAdd(&data->arguments, token);
    }
    *datap = data;
}
示例#8
0
void
refreshCheckInit(void)
{
    static int firstTimeInit = 1;
    refresh_check_helper *p = Config.Program.refresh_check;

    if (p) {
	if (!p->helper)
	    p->helper = helperCreate("external_refresh_check");
	p->helper->cmdline = p->cmdline;
	p->helper->n_to_start = p->children;
	p->helper->concurrency = p->concurrency;
	p->helper->ipc_type = IPC_STREAM;
	helperOpenServers(p->helper);
	if (firstTimeInit) {
	    firstTimeInit = 0;
	    cachemgrRegister("refresh_check",
		"External ACL stats",
		refreshCheckStats, 0, 1);
	}
	CBDATA_INIT_TYPE_FREECB(refreshCheckState, free_refreshCheckState);
    }
}
void
externalAclInit(void)
{
    static int firstTimeInit = 1;
    external_acl *p;

    for (p = Config.externalAclHelperList; p; p = p->next) {
	if (!p->cache)
	    p->cache = hash_create((HASHCMP *) strcmp, hashPrime(1024), hash4);
	if (!p->helper)
	    p->helper = helperCreate(p->name);
	p->helper->cmdline = p->cmdline;
	p->helper->n_to_start = p->children;
	p->helper->ipc_type = IPC_TCP_SOCKET;
	helperOpenServers(p->helper);
    }
    if (firstTimeInit) {
	firstTimeInit = 0;
	cachemgrRegister("external_acl",
	    "External ACL stats",
	    externalAclStats, 0, 1);
	CBDATA_INIT_TYPE_FREECB(externalAclState, free_externalAclState);
    }
}
static external_acl_entry *
external_acl_cache_add(external_acl * def, const char *key, int result, char *user, char *error)
{
    external_acl_entry *entry = hash_lookup(def->cache, key);
    debug(82, 2) ("external_acl_cache_add: Adding '%s' = %d\n", key, result);
    if (entry) {
	debug(82, 3) ("external_acl_cache_add: updating existing entry\n");
	entry->date = squid_curtime;
	entry->result = result;
	safe_free(entry->user);
	safe_free(entry->error);
	if (user)
	    entry->user = xstrdup(user);
	if (error)
	    entry->error = xstrdup(error);
	external_acl_cache_touch(def, entry);
	return entry;
    }
    CBDATA_INIT_TYPE_FREECB(external_acl_entry, free_external_acl_entry);
    /* Maintain cache size */
    if (def->cache_size && def->cache_entries >= def->cache_size)
	external_acl_cache_delete(def, def->lru_list.tail->data);
    entry = cbdataAlloc(external_acl_entry);
    entry->hash.key = xstrdup(key);
    entry->date = squid_curtime;
    entry->result = result;
    if (user)
	entry->user = xstrdup(user);
    if (error)
	entry->error = xstrdup(error);
    entry->def = def;
    hash_join(def->cache, &entry->hash);
    dlinkAdd(entry, &entry->lru, &def->lru_list);
    def->cache_entries += 1;
    return entry;
}
void
parse_externalAclHelper(external_acl ** list)
{
    external_acl *a;
    char *token;
    external_acl_format **p;

    CBDATA_INIT_TYPE_FREECB(external_acl, free_external_acl);
    CBDATA_INIT_TYPE_FREECB(external_acl_format, free_external_acl_format);

    a = cbdataAlloc(external_acl);

    a->ttl = DEFAULT_EXTERNAL_ACL_TTL;
    a->negative_ttl = -1;
    a->children = DEFAULT_EXTERNAL_ACL_CONCURRENCY;

    token = strtok(NULL, w_space);
    if (!token)
	self_destruct();
    a->name = xstrdup(token);

    token = strtok(NULL, w_space);
    /* Parse options */
    while (token) {
	if (strncmp(token, "ttl=", 4) == 0) {
	    a->ttl = atoi(token + 4);
	} else if (strncmp(token, "negative_ttl=", 13) == 0) {
	    a->negative_ttl = atoi(token + 13);
	} else if (strncmp(token, "children=", 9) == 0) {
	    a->children = atoi(token + 9);
	} else if (strncmp(token, "concurrency=", 12) == 0) {
	    a->children = atoi(token + 12);
	} else if (strncmp(token, "cache=", 6) == 0) {
	    a->cache_size = atoi(token + 6);
	} else {
	    break;
	}

	token = strtok(NULL, w_space);
    }
    if (a->negative_ttl == -1)
	a->negative_ttl = a->ttl;

    /* Parse format */
    p = &a->format;
    while (token) {
	external_acl_format *format;

	/* stop on first non-format token found */
	if (*token != '%')
	    break;

	format = cbdataAlloc(external_acl_format);

	if (strncmp(token, "%{", 2) == 0) {
	    /* header format */
	    char *header, *member, *end;
	    header = token + 2;
	    end = strchr(header, '}');
	    /* cut away the terminating } */
	    if (end && strlen(end) == 1)
		*end = '\0';
	    else
		self_destruct();

	    member = strchr(header, ':');
	    if (member) {
		/* Split in header and member */
		*member++ = '\0';
		if (!isalnum(*member))
		    format->separator = *member++;
		else
		    format->separator = ',';
		format->member = xstrdup(member);
		format->type = EXT_ACL_HEADER_MEMBER;
	    } else {
		format->type = EXT_ACL_HEADER;
	    }
	    format->header = xstrdup(header);
	    format->header_id = httpHeaderIdByNameDef(header, strlen(header));
	    if (format->header_id != -1) {
		if (member)
		    format->type = EXT_ACL_HEADER_ID_MEMBER;
		else
		    format->type = EXT_ACL_HEADER_ID;
	    }
	} else if (strcmp(token, "%LOGIN") == 0) {
	    format->type = EXT_ACL_LOGIN;
	    a->require_auth = 1;
	}
#if USE_IDENT
	else if (strcmp(token, "%IDENT") == 0)
	    format->type = EXT_ACL_IDENT;
#endif
	else if (strcmp(token, "%SRC") == 0)
	    format->type = EXT_ACL_SRC;
	else if (strcmp(token, "%DST") == 0)
	    format->type = EXT_ACL_DST;
	else if (strcmp(token, "%PROTO") == 0)
	    format->type = EXT_ACL_PROTO;
	else if (strcmp(token, "%PORT") == 0)
	    format->type = EXT_ACL_PORT;
	else if (strcmp(token, "%METHOD") == 0)
	    format->type = EXT_ACL_METHOD;
	else {
	    self_destruct();
	}
	*p = format;
	p = &format->next;
	token = strtok(NULL, w_space);
    }

    /* There must be at least one format token */
    if (!a->format)
	self_destruct();

    /* helper */
    if (!token)
	self_destruct();
    wordlistAdd(&a->cmdline, token);

    /* arguments */
    parse_wordlist(&a->cmdline);

    while (*list)
	list = &(*list)->next;
    *list = a;
}
static int sys_init()
{
	CBDATA_INIT_TYPE_FREECB(server, free_server);
	return 0;
	
}
示例#13
0
void
parse_refreshCheckHelper(refresh_check_helper ** ptr)
{
    refresh_check_helper *a;
    char *token;
    refresh_check_format **p;

    if (*ptr)
	self_destruct();

    CBDATA_INIT_TYPE_FREECB(refresh_check_helper, free_refresh_check_helper);
    CBDATA_INIT_TYPE_FREECB(refresh_check_format, free_refresh_check_format);

    a = cbdataAlloc(refresh_check_helper);

    a->children = DEFAULT_REFRESH_CHECK_CHILDREN;

    /* Parse options */
    while ((token = strtok(NULL, w_space)) != NULL) {
	if (strncmp(token, "children=", 9) == 0) {
	    a->children = atoi(token + 9);
	} else if (strncmp(token, "concurrency=", 12) == 0) {
	    a->concurrency = atoi(token + 12);
	} else {
	    break;
	}
    }

    /* Parse format */
    p = &a->format;
    while (token) {
	refresh_check_format *format;

	/* stop on first non-format token found */
	if (*token != '%')
	    break;

	format = cbdataAlloc(refresh_check_format);

	if (strncmp(token, "%RES{", 5) == 0) {
	    /* header format */
	    char *header, *member, *end;
	    header = token + 5;
	    end = strchr(header, '}');
	    /* cut away the terminating } */
	    if (end && strlen(end) == 1)
		*end = '\0';
	    else
		self_destruct();

	    member = strchr(header, ':');
	    if (member) {
		/* Split in header and member */
		*member++ = '\0';
		if (!xisalnum(*member))
		    format->separator = *member++;
		else
		    format->separator = ',';
		format->member = xstrdup(member);
		format->type = REFRESH_CHECK_RESP_HEADER_MEMBER;
	    } else {
		format->type = REFRESH_CHECK_RESP_HEADER;
	    }
	    format->header = xstrdup(header);
	    format->header_id = httpHeaderIdByNameDef(header, strlen(header));
	    if (format->header_id != -1) {
		if (member)
		    format->type = REFRESH_CHECK_RESP_HEADER_ID_MEMBER;
		else
		    format->type = REFRESH_CHECK_RESP_HEADER_ID;
	    }
	} else if (strcmp(token, "%URI") == 0)
	    format->type = REFRESH_CHECK_URI;
	else if (strcmp(token, "%URL") == 0)
	    format->type = REFRESH_CHECK_URI;
	else if (strcmp(token, "%CACHE_URI") == 0)
	    format->type = REFRESH_CHECK_URI;
	else if (strcmp(token, "%AGE") == 0)
	    format->type = REFRESH_CHECK_AGE;
	else {
	    self_destruct();
	}
	*p = format;
	p = &format->next;
	token = strtok(NULL, w_space);
    }
    /* There must be at least one format token */
    if (!a->format)
	self_destruct();

    /* helper */
    if (!token)
	self_destruct();
    wordlistAdd(&a->cmdline, token);

    /* arguments */
    parse_wordlist(&a->cmdline);

    *ptr = a;
}
示例#14
0
void
storeUpdate(StoreEntry * entry, request_t * request)
{
    StoreUpdateState *state;
    request_flags flags = null_request_flags;
    const char *vary;

    if (!request)
	request = entry->mem_obj->request;

    if (EBIT_TEST(entry->flags, KEY_PRIVATE))
	return;			/* Nothing to do here... */

    if (!Config.onoff.update_headers)
	return;			/* Disabled */

    CBDATA_INIT_TYPE_FREECB(StoreUpdateState, free_StoreUpdateState);

    if (entry->mem_obj)
	entry->mem_obj->refresh_timestamp = 0;
    state = cbdataAlloc(StoreUpdateState);
    state->oldentry = entry;
    storeLockObject(state->oldentry);
    flags.cachable = 1;
    state->newentry = storeCreateEntry(storeUrl(entry), flags, entry->mem_obj->method);
    storeRegisterAbort(state->newentry, storeUpdateAbort, state);
    state->sc = storeClientRegister(state->oldentry, state);
    state->offset = entry->mem_obj->reply->hdr_sz;
    storeBuffer(state->newentry);
    httpReplySwapOut(httpReplyClone(entry->mem_obj->reply), state->newentry);
    state->newentry->timestamp = entry->timestamp;
    state->newentry->lastref = entry->lastref;
    state->newentry->expires = entry->expires;
    state->newentry->lastmod = entry->lastmod;
    state->newentry->refcount = entry->refcount;
    if (request) {
	state->newentry->mem_obj->request = requestLink(request);
	vary = httpMakeVaryMark(request, state->newentry->mem_obj->reply);
	if (vary) {
	    state->newentry->mem_obj->vary_headers = xstrdup(vary);
	    if (strBuf(request->vary_encoding))
		state->newentry->mem_obj->vary_encoding = xstrdup(strBuf(request->vary_encoding));
	}
    } else {
	if (entry->mem_obj->vary_headers)
	    state->newentry->mem_obj->vary_headers = xstrdup(entry->mem_obj->vary_headers);
	if (entry->mem_obj->vary_encoding)
	    state->newentry->mem_obj->vary_encoding = xstrdup(entry->mem_obj->vary_encoding);
    }
    storeSetPublicKey(state->newentry);
    storeBufferFlush(state->newentry);
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	/*
	 * the above storeBufferFlush() call could ABORT this entry,
	 * in that case, there's nothing for us to do.
	 */
	debug(20, 1) ("storeUpdate: Aborted on write\n");
	return;
    }
    storeClientCopy(state->sc, state->oldentry, state->offset, state->offset, sizeof(state->buf), state->buf, storeUpdateCopy, state);
    return;
}