1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

xs: Remove redundant validity checks, clean up function headers

Arguments for driver entry points are checked in libvirt.c, so no need to
check again. Make function entry points consistent.
This commit is contained in:
John Ferlan 2013-01-28 17:22:28 -05:00
parent fe69656ea9
commit 2ca9c3cefe

View File

@ -1,7 +1,7 @@
/* /*
* xs_internal.c: access to Xen Store * xs_internal.c: access to Xen Store
* *
* Copyright (C) 2006, 2009-2012 Red Hat, Inc. * Copyright (C) 2006, 2009-2013 Red Hat, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -83,17 +83,9 @@ struct xenUnifiedDriver xenStoreDriver = {
* Returns a string which must be freed by the caller or NULL in case of error * Returns a string which must be freed by the caller or NULL in case of error
*/ */
static char ** static char **
virConnectDoStoreList(virConnectPtr conn, const char *path, virConnectDoStoreList(virConnectPtr conn, const char *path, unsigned int *nb)
unsigned int *nb)
{ {
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (conn == NULL)
return NULL;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL || path == NULL || nb == NULL)
return NULL;
return xs_directory(priv->xshandle, 0, path, nb); return xs_directory(priv->xshandle, 0, path, nb);
} }
@ -113,12 +105,8 @@ virDomainDoStoreQuery(virConnectPtr conn, int domid, const char *path)
{ {
char s[256]; char s[256];
unsigned int len = 0; unsigned int len = 0;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (!conn)
return NULL;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return NULL; return NULL;
@ -139,20 +127,13 @@ virDomainDoStoreQuery(virConnectPtr conn, int domid, const char *path)
* Returns 0 in case of success, -1 in case of failure * Returns 0 in case of success, -1 in case of failure
*/ */
static int static int
virDomainDoStoreWrite(virDomainPtr domain, const char *path, virDomainDoStoreWrite(virDomainPtr domain, const char *path, const char *value)
const char *value)
{ {
char s[256]; char s[256];
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
int ret = -1; int ret = -1;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) if (priv->xshandle == NULL || domain->conn->flags & VIR_CONNECT_RO)
return -1;
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
if (priv->xshandle == NULL)
return -1;
if (domain->conn->flags & VIR_CONNECT_RO)
return -1; return -1;
snprintf(s, 255, "/local/domain/%d/%s", domain->id, path); snprintf(s, 255, "/local/domain/%d/%s", domain->id, path);
@ -178,12 +159,8 @@ virDomainGetVM(virDomainPtr domain)
char *vm; char *vm;
char query[200]; char query[200];
unsigned int len; unsigned int len;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
if (!VIR_IS_CONNECTED_DOMAIN(domain))
return NULL;
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return NULL; return NULL;
@ -212,12 +189,8 @@ virDomainGetVMInfo(virDomainPtr domain, const char *vm, const char *name)
char s[256]; char s[256];
char *ret = NULL; char *ret = NULL;
unsigned int len = 0; unsigned int len = 0;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
if (!VIR_IS_CONNECTED_DOMAIN(domain))
return NULL;
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return NULL; return NULL;
@ -250,7 +223,7 @@ xenStoreOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED, virConnectAuthPtr auth ATTRIBUTE_UNUSED,
unsigned int flags) unsigned int flags)
{ {
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData; xenUnifiedPrivatePtr priv = conn->privateData;
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
@ -326,14 +299,7 @@ xenStoreOpen(virConnectPtr conn,
int int
xenStoreClose(virConnectPtr conn) xenStoreClose(virConnectPtr conn)
{ {
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (conn == NULL) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (xenStoreRemoveWatch(conn, "@introduceDomain", "introduceDomain") < 0) { if (xenStoreRemoveWatch(conn, "@introduceDomain", "introduceDomain") < 0) {
VIR_DEBUG("Warning, could not remove @introduceDomain watch"); VIR_DEBUG("Warning, could not remove @introduceDomain watch");
@ -377,21 +343,9 @@ xenStoreGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
char *tmp, **tmp2; char *tmp, **tmp2;
unsigned int nb_vcpus; unsigned int nb_vcpus;
char request[200]; char request[200];
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) if (priv->xshandle == NULL || domain->id == -1)
return -1;
if ((domain == NULL) || (domain->conn == NULL) || (info == NULL)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
if (priv->xshandle == NULL)
return -1;
if (domain->id == -1)
return -1; return -1;
tmp = virDomainDoStoreQuery(domain->conn, domain->id, "running"); tmp = virDomainDoStoreQuery(domain->conn, domain->id, "running");
@ -482,8 +436,7 @@ xenStoreDomainSetMemory(virDomainPtr domain, unsigned long memory)
int ret; int ret;
char value[20]; char value[20];
if ((domain == NULL) || (domain->conn == NULL) || if (memory < 1024 * MIN_XEN_GUEST_SIZE) {
(memory < 1024 * MIN_XEN_GUEST_SIZE)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1; return -1;
} }
@ -512,14 +465,11 @@ xenStoreDomainGetMaxMemory(virDomainPtr domain)
{ {
char *tmp; char *tmp;
unsigned long long ret = 0; unsigned long long ret = 0;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
if (!VIR_IS_CONNECTED_DOMAIN(domain))
return ret;
if (domain->id == -1) if (domain->id == -1)
return 0; return 0;
priv = domain->conn->privateData;
xenUnifiedLock(priv); xenUnifiedLock(priv);
tmp = virDomainDoStoreQuery(domain->conn, domain->id, "memory/target"); tmp = virDomainDoStoreQuery(domain->conn, domain->id, "memory/target");
if (tmp != NULL) { if (tmp != NULL) {
@ -545,14 +495,8 @@ xenStoreNumOfDomains(virConnectPtr conn)
char **idlist = NULL, *endptr; char **idlist = NULL, *endptr;
int i, ret = -1, realnum = 0; int i, ret = -1, realnum = 0;
long id; long id;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (conn == NULL) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL) { if (priv->xshandle == NULL) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1; return -1;
@ -589,7 +533,10 @@ out:
* Returns the number of domain found or -1 in case of error * Returns the number of domain found or -1 in case of error
*/ */
static int static int
xenStoreDoListDomains(virConnectPtr conn, xenUnifiedPrivatePtr priv, int *ids, int maxids) xenStoreDoListDomains(virConnectPtr conn,
xenUnifiedPrivatePtr priv,
int *ids,
int maxids)
{ {
char **idlist = NULL, *endptr; char **idlist = NULL, *endptr;
unsigned int num, i; unsigned int num, i;
@ -632,16 +579,9 @@ out:
int int
xenStoreListDomains(virConnectPtr conn, int *ids, int maxids) xenStoreListDomains(virConnectPtr conn, int *ids, int maxids)
{ {
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
int ret; int ret;
if ((conn == NULL) || (ids == NULL)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
priv = (xenUnifiedPrivatePtr) conn->privateData;
xenUnifiedLock(priv); xenUnifiedLock(priv);
ret = xenStoreDoListDomains(conn, priv, ids, maxids); ret = xenStoreDoListDomains(conn, priv, ids, maxids);
xenUnifiedUnlock(priv); xenUnifiedUnlock(priv);
@ -668,14 +608,8 @@ xenStoreLookupByName(virConnectPtr conn, const char *name)
char prop[200], *tmp; char prop[200], *tmp;
int found = 0; int found = 0;
struct xend_domain *xenddomain = NULL; struct xend_domain *xenddomain = NULL;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if ((conn == NULL) || (name == NULL)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return NULL;
}
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return NULL; return NULL;
@ -732,19 +666,14 @@ int
xenStoreDomainShutdown(virDomainPtr domain) xenStoreDomainShutdown(virDomainPtr domain)
{ {
int ret; int ret;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
if ((domain == NULL) || (domain->conn == NULL)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->id == -1 || domain->id == 0) if (domain->id == -1 || domain->id == 0)
return -1; return -1;
/* /*
* this is very hackish, the domU kernel probes for a special * this is very hackish, the domU kernel probes for a special
* node in the xenstore and launch the shutdown command if found. * node in the xenstore and launch the shutdown command if found.
*/ */
priv = domain->conn->privateData;
xenUnifiedLock(priv); xenUnifiedLock(priv);
ret = virDomainDoStoreWrite(domain, "control/shutdown", "poweroff"); ret = virDomainDoStoreWrite(domain, "control/shutdown", "poweroff");
xenUnifiedUnlock(priv); xenUnifiedUnlock(priv);
@ -766,21 +695,17 @@ int
xenStoreDomainReboot(virDomainPtr domain, unsigned int flags) xenStoreDomainReboot(virDomainPtr domain, unsigned int flags)
{ {
int ret; int ret;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = domain->conn->privateData;
virCheckFlags(0, -1); virCheckFlags(0, -1);
if ((domain == NULL) || (domain->conn == NULL)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->id == -1 || domain->id == 0) if (domain->id == -1 || domain->id == 0)
return -1; return -1;
/* /*
* this is very hackish, the domU kernel probes for a special * this is very hackish, the domU kernel probes for a special
* node in the xenstore and launch the shutdown command if found. * node in the xenstore and launch the shutdown command if found.
*/ */
priv = domain->conn->privateData;
xenUnifiedLock(priv); xenUnifiedLock(priv);
ret = virDomainDoStoreWrite(domain, "control/shutdown", "reboot"); ret = virDomainDoStoreWrite(domain, "control/shutdown", "reboot");
xenUnifiedUnlock(priv); xenUnifiedUnlock(priv);
@ -797,14 +722,10 @@ xenStoreDomainReboot(virDomainPtr domain, unsigned int flags)
* freed by the caller. * freed by the caller.
*/ */
static char * static char *
xenStoreDomainGetOSType(virDomainPtr domain) { xenStoreDomainGetOSType(virDomainPtr domain)
{
char *vm, *str = NULL; char *vm, *str = NULL;
if ((domain == NULL) || (domain->conn == NULL)) {
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return NULL;
}
vm = virDomainGetVM(domain); vm = virDomainGetVM(domain);
if (vm) { if (vm) {
xenUnifiedPrivatePtr priv = domain->conn->privateData; xenUnifiedPrivatePtr priv = domain->conn->privateData;
@ -830,7 +751,9 @@ xenStoreDomainGetOSType(virDomainPtr domain) {
* *
* Returns the port number, -1 in case of error * Returns the port number, -1 in case of error
*/ */
int xenStoreDomainGetVNCPort(virConnectPtr conn, int domid) { int
xenStoreDomainGetVNCPort(virConnectPtr conn, int domid)
{
char *tmp; char *tmp;
int ret = -1; int ret = -1;
@ -860,7 +783,9 @@ int xenStoreDomainGetVNCPort(virConnectPtr conn, int domid) {
* The caller must hold the lock on the privateData * The caller must hold the lock on the privateData
* associated with the 'conn' parameter. * associated with the 'conn' parameter.
*/ */
char * xenStoreDomainGetConsolePath(virConnectPtr conn, int domid) { char *
xenStoreDomainGetConsolePath(virConnectPtr conn, int domid)
{
return virDomainDoStoreQuery(conn, domid, "console/tty"); return virDomainDoStoreQuery(conn, domid, "console/tty");
} }
@ -879,7 +804,9 @@ char * xenStoreDomainGetConsolePath(virConnectPtr conn, int domid) {
* The caller must hold the lock on the privateData * The caller must hold the lock on the privateData
* associated with the 'conn' parameter. * associated with the 'conn' parameter.
*/ */
char * xenStoreDomainGetSerialConsolePath(virConnectPtr conn, int domid) { char *
xenStoreDomainGetSerialConsolePath(virConnectPtr conn, int domid)
{
return virDomainDoStoreQuery(conn, domid, "serial/0/tty"); return virDomainDoStoreQuery(conn, domid, "serial/0/tty");
} }
@ -900,19 +827,14 @@ char * xenStoreDomainGetSerialConsolePath(virConnectPtr conn, int domid) {
* freed by the caller. * freed by the caller.
*/ */
char * char *
xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac) { xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac)
{
char dir[80], path[128], **list = NULL, *val = NULL; char dir[80], path[128], **list = NULL, *val = NULL;
unsigned int len, i, num; unsigned int len, i, num;
char *ret = NULL; char *ret = NULL;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (id < 0) if (id < 0 || priv->xshandle == NULL || mac == NULL)
return NULL;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL)
return NULL;
if (mac == NULL)
return NULL; return NULL;
snprintf(dir, sizeof(dir), "/local/domain/0/backend/vif/%d", id); snprintf(dir, sizeof(dir), "/local/domain/0/backend/vif/%d", id);
@ -958,19 +880,14 @@ xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac) {
* freed by the caller. * freed by the caller.
*/ */
char * char *
xenStoreDomainGetDiskID(virConnectPtr conn, int id, const char *dev) { xenStoreDomainGetDiskID(virConnectPtr conn, int id, const char *dev)
{
char dir[80], path[128], **list = NULL, *val = NULL; char dir[80], path[128], **list = NULL, *val = NULL;
unsigned int devlen, len, i, num; unsigned int devlen, len, i, num;
char *ret = NULL; char *ret = NULL;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (id < 0) if (id < 0 || priv->xshandle == NULL || dev == NULL)
return NULL;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL)
return NULL;
if (dev == NULL)
return NULL; return NULL;
devlen = strlen(dev); devlen = strlen(dev);
if (devlen <= 0) if (devlen <= 0)
@ -1046,15 +963,9 @@ xenStoreDomainGetPCIID(virConnectPtr conn, int id, const char *bdf)
char dir[80], path[128], **list = NULL, *val = NULL; char dir[80], path[128], **list = NULL, *val = NULL;
unsigned int len, i, num; unsigned int len, i, num;
char *ret = NULL; char *ret = NULL;
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
if (id < 0) if (id < 0 || priv->xshandle == NULL || bdf == NULL)
return NULL;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL)
return NULL;
if (bdf == NULL)
return NULL; return NULL;
snprintf(dir, sizeof(dir), "/local/domain/0/backend/pci/%d", id); snprintf(dir, sizeof(dir), "/local/domain/0/backend/pci/%d", id);
@ -1084,13 +995,13 @@ xenStoreDomainGetPCIID(virConnectPtr conn, int id, const char *bdf)
* The caller must hold the lock on the privateData * The caller must hold the lock on the privateData
* associated with the 'conn' parameter. * associated with the 'conn' parameter.
*/ */
char *xenStoreDomainGetName(virConnectPtr conn, char *
int id) { xenStoreDomainGetName(virConnectPtr conn, int id)
{
char prop[200]; char prop[200];
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
unsigned int len; unsigned int len;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return NULL; return NULL;
@ -1103,16 +1014,15 @@ char *xenStoreDomainGetName(virConnectPtr conn,
* The caller must hold the lock on the privateData * The caller must hold the lock on the privateData
* associated with the 'conn' parameter. * associated with the 'conn' parameter.
*/ */
int xenStoreDomainGetUUID(virConnectPtr conn, int
int id, xenStoreDomainGetUUID(virConnectPtr conn, int id, unsigned char *uuid)
unsigned char *uuid) { {
char prop[200]; char prop[200];
xenUnifiedPrivatePtr priv; xenUnifiedPrivatePtr priv = conn->privateData;
unsigned int len; unsigned int len;
char *uuidstr; char *uuidstr;
int ret = 0; int ret = 0;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return -1; return -1;
@ -1149,16 +1059,17 @@ xenStoreWatchListFree(xenStoreWatchListPtr list)
* The caller must hold the lock on the privateData * The caller must hold the lock on the privateData
* associated with the 'conn' parameter. * associated with the 'conn' parameter.
*/ */
int xenStoreAddWatch(virConnectPtr conn, int
const char *path, xenStoreAddWatch(virConnectPtr conn,
const char *token, const char *path,
xenStoreWatchCallback cb, const char *token,
void *opaque) xenStoreWatchCallback cb,
void *opaque)
{ {
xenStoreWatchPtr watch = NULL; xenStoreWatchPtr watch = NULL;
int n; int n;
xenStoreWatchListPtr list; xenStoreWatchListPtr list;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData; xenUnifiedPrivatePtr priv = conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return -1; return -1;
@ -1216,13 +1127,12 @@ int xenStoreAddWatch(virConnectPtr conn,
* The caller must hold the lock on the privateData * The caller must hold the lock on the privateData
* associated with the 'conn' parameter. * associated with the 'conn' parameter.
*/ */
int xenStoreRemoveWatch(virConnectPtr conn, int
const char *path, xenStoreRemoveWatch(virConnectPtr conn, const char *path, const char *token)
const char *token)
{ {
int i; int i;
xenStoreWatchListPtr list; xenStoreWatchListPtr list;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData; xenUnifiedPrivatePtr priv = conn->privateData;
if (priv->xshandle == NULL) if (priv->xshandle == NULL)
return -1; return -1;
@ -1281,8 +1191,7 @@ xenStoreFindWatch(xenStoreWatchListPtr list,
static void static void
xenStoreWatchEvent(int watch ATTRIBUTE_UNUSED, xenStoreWatchEvent(int watch ATTRIBUTE_UNUSED,
int fd ATTRIBUTE_UNUSED, int fd ATTRIBUTE_UNUSED,
int events, int events, void *data)
void *data)
{ {
char **event; char **event;
char *path; char *path;
@ -1291,7 +1200,7 @@ xenStoreWatchEvent(int watch ATTRIBUTE_UNUSED,
xenStoreWatchPtr sw; xenStoreWatchPtr sw;
virConnectPtr conn = data; virConnectPtr conn = data;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData; xenUnifiedPrivatePtr priv = conn->privateData;
if (!priv) return; if (!priv) return;
@ -1325,10 +1234,11 @@ cleanup:
* *
* The lock on 'priv' is held when calling this * The lock on 'priv' is held when calling this
*/ */
int xenStoreDomainIntroduced(virConnectPtr conn, int
const char *path ATTRIBUTE_UNUSED, xenStoreDomainIntroduced(virConnectPtr conn,
const char *token ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED,
void *opaque) const char *token ATTRIBUTE_UNUSED,
void *opaque)
{ {
int i, j, found, missing = 0, retries = 20; int i, j, found, missing = 0, retries = 20;
int new_domain_cnt; int new_domain_cnt;
@ -1406,17 +1316,18 @@ retry:
* *
* The lock on 'priv' is held when calling this * The lock on 'priv' is held when calling this
*/ */
int xenStoreDomainReleased(virConnectPtr conn, int
const char *path ATTRIBUTE_UNUSED, xenStoreDomainReleased(virConnectPtr conn,
const char *token ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED,
void *opaque) const char *token ATTRIBUTE_UNUSED,
void *opaque)
{ {
int i, j, found, removed, retries = 20; int i, j, found, removed, retries = 20;
int new_domain_cnt; int new_domain_cnt;
int *new_domids; int *new_domids;
int nread; int nread;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) opaque; xenUnifiedPrivatePtr priv = opaque;
if (!priv->activeDomainList->count) return 0; if (!priv->activeDomainList->count) return 0;