diff options
Diffstat (limited to 'usr/src/lib/libvscan/common/libvscan.c')
| -rw-r--r-- | usr/src/lib/libvscan/common/libvscan.c | 222 |
1 files changed, 137 insertions, 85 deletions
diff --git a/usr/src/lib/libvscan/common/libvscan.c b/usr/src/lib/libvscan/common/libvscan.c index f7d5170750..cfd012c2b2 100644 --- a/usr/src/lib/libvscan/common/libvscan.c +++ b/usr/src/lib/libvscan/common/libvscan.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -48,8 +48,8 @@ /* SMF property group and property names */ #define VS_PGNAME_GENERAL "vs_general" -#define VS_PGNAME_ENGINE "vs_engine_%d" -#define VS_PGNAME_ENGINE_LEN 16 +#define VS_PGNAME_ENGINE_PREFIX "vs_engine_" +#define VS_PGNAME_ENGINE_LEN VS_SE_NAME_LEN + 16 #define VS_PNAME_MAXSIZE "maxsize" #define VS_PNAME_MAXSIZE_ACTION "maxsize_action" @@ -166,6 +166,7 @@ static int vs_scf_get(const vs_propdef_t *, vs_prop_hd_t *, vs_scfctx_t *, int); static int vs_scf_values_set(const char *, vs_prop_hd_t *); static int vs_scf_set(const vs_propdef_t *, vs_prop_hd_t *, vs_scfctx_t *, int); static int vs_scf_pg_create(const char *, vs_prop_hd_t *); +static int vs_scf_pg_delete(const char *); static int vs_scf_ctx_open(vs_scfctx_t *); static void vs_scf_ctx_close(vs_scfctx_t *); @@ -175,8 +176,8 @@ static int vs_is_valid_types(const char *); static int vs_is_valid_host(const char *); static int vs_checkauth(char *); -typedef char vs_engid_t[VS_SE_NAME_LEN]; -static int vs_props_get_engines(vs_engid_t *engids, int *count); +static int vs_props_get_engines(char *[], int *); +static void vs_engid_to_pgname(const char *, char [VS_PGNAME_ENGINE_LEN]); static int vs_scf_pg_count(void); static int vs_strtoshift(const char *); @@ -199,8 +200,7 @@ int vs_props_get_all(vs_props_all_t *va) { int i, rc, n; - char *engid; - vs_engid_t engids[VS_SE_MAX]; + char *engids[VS_SE_MAX]; (void) memset(va, 0, sizeof (vs_props_all_t)); if ((rc = vs_props_get(&va->va_props, VS_PROPID_GEN_ALL)) @@ -211,17 +211,19 @@ vs_props_get_all(vs_props_all_t *va) if ((rc = vs_props_get_engines(engids, &n)) != VS_ERR_NONE) return (rc); - if (n > VS_SE_MAX) - n = VS_SE_MAX; - for (i = 0; i < n; i++) { - engid = engids[i]; - rc = vs_props_se_get(engid, &va->va_se[i], VS_PROPID_SE_ALL); - if (rc != VS_ERR_NONE) - return (rc); + if ((rc = vs_props_se_get(engids[i], + &va->va_se[i], VS_PROPID_SE_ALL)) != VS_ERR_NONE) + break; } - return (VS_ERR_NONE); + /* free engids allocated in vs_props_get_engines */ + for (i = 0; i < VS_SE_MAX; i++) { + if (engids[i] != NULL) + free(engids[i]); + } + + return (rc); } @@ -311,6 +313,7 @@ int vs_props_se_get(char *engid, vs_props_se_t *sep, uint64_t propids) { int rc; + char pgname[VS_PGNAME_ENGINE_LEN]; vs_prop_hd_t prop_hd; /* VS_PGNAME_GENERAL is a reserved for GENERAL property group */ @@ -331,7 +334,8 @@ vs_props_se_get(char *engid, vs_props_se_t *sep, uint64_t propids) prop_hd.vp_ids |= VS_PROPID_SE_HOST; /* Load values from the repository */ - rc = vs_scf_values_get(engid, &prop_hd); + vs_engid_to_pgname(engid, pgname); + rc = vs_scf_values_get(pgname, &prop_hd); if (rc != VS_ERR_NONE) return (rc); @@ -371,6 +375,7 @@ int vs_props_se_set(char *engid, const vs_props_se_t *sep, uint64_t propids) { int rc; + char pgname[VS_PGNAME_ENGINE_LEN]; vs_prop_hd_t prop_hd; /* VS_PGNAME_GENERAL is a reserved for GENERAL property group */ @@ -384,6 +389,8 @@ vs_props_se_set(char *engid, const vs_props_se_t *sep, uint64_t propids) prop_hd.vp_type = VS_PTYPE_SE; prop_hd.vp_all = VS_PROPID_SE_ALL; + vs_engid_to_pgname(engid, pgname); + /* * if enabling a scan engine, ensure that a valid host * is also being set, or already exists in the repository @@ -392,7 +399,7 @@ vs_props_se_set(char *engid, const vs_props_se_t *sep, uint64_t propids) !(propids & VS_PROPID_SE_HOST)) { prop_hd.vp_ids = VS_PROPID_SE_HOST; - if ((rc = vs_scf_values_get(engid, &prop_hd)) != VS_ERR_NONE) + if ((rc = vs_scf_values_get(pgname, &prop_hd)) != VS_ERR_NONE) return (rc); if (vs_validate(&prop_hd, VS_PROPID_SE_HOST) != VS_ERR_NONE) @@ -402,7 +409,7 @@ vs_props_se_set(char *engid, const vs_props_se_t *sep, uint64_t propids) prop_hd.vp_ids = propids; prop_hd.vp_se = *sep; - return (vs_scf_values_set(engid, &prop_hd)); + return (vs_scf_values_set(pgname, &prop_hd)); } @@ -413,6 +420,7 @@ int vs_props_se_create(char *engid, const vs_props_se_t *sep, uint64_t propids) { int n; + char pgname[VS_PGNAME_ENGINE_LEN]; vs_prop_hd_t prop_hd; if ((propids & VS_PROPID_SE_ALL) != propids) @@ -428,14 +436,21 @@ vs_props_se_create(char *engid, const vs_props_se_t *sep, uint64_t propids) if (n == VS_SE_MAX) return (VS_ERR_MAX_SE); + vs_engid_to_pgname(engid, pgname); + (void) memset(&prop_hd, 0, sizeof (vs_prop_hd_t)); prop_hd.vp_type = VS_PTYPE_SE; prop_hd.vp_all = VS_PROPID_SE_ALL; prop_hd.vp_ids = propids | VS_PROPID_VALUE_AUTH; prop_hd.vp_se = *sep; - return (vs_scf_pg_create(engid, &prop_hd)); + /* if hostname not specified, default it to engid */ + if ((propids & VS_PROPID_SE_HOST) == 0) { + (void) strlcpy(prop_hd.vp_se.vep_host, engid, MAXHOSTNAMELEN); + prop_hd.vp_ids |= VS_PROPID_SE_HOST; + } + return (vs_scf_pg_create(pgname, &prop_hd)); } @@ -445,50 +460,15 @@ vs_props_se_create(char *engid, const vs_props_se_t *sep, uint64_t propids) int vs_props_se_delete(const char *engid) { - int rc; - vs_scfctx_t vsc; + char pgname[VS_PGNAME_ENGINE_LEN]; /* VS_PGNAME_GENERAL is a reserved for GENERAL property group */ if (strcmp(engid, VS_PGNAME_GENERAL) == 0) return (VS_ERR_INVALID_SE); - /* ensure that caller has authorization to refresh service */ - if ((rc = vs_checkauth(VS_ACTION_AUTH)) != VS_ERR_NONE) - return (rc); - - if (vs_scf_ctx_open(&vsc) != 0) { - vs_scf_ctx_close(&vsc); - return (VS_ERR_SCF); - } - - if (scf_instance_get_pg(vsc.vscf_inst, engid, vsc.vscf_pgroup) == -1) { - vs_scf_ctx_close(&vsc); - rc = scf_error(); - if ((rc == SCF_ERROR_NOT_FOUND) || - (rc == SCF_ERROR_INVALID_ARGUMENT)) - return (VS_ERR_INVALID_SE); - else - return (VS_ERR_SCF); - } - - if (scf_pg_delete(vsc.vscf_pgroup) == -1) { - vs_scf_ctx_close(&vsc); - rc = scf_error(); - if ((rc == SCF_ERROR_NOT_FOUND) || - (rc == SCF_ERROR_INVALID_ARGUMENT)) - return (VS_ERR_INVALID_SE); - - return (VS_ERR_SCF); - } - - vs_scf_ctx_close(&vsc); - - /* Notify the daemon that things have changed */ - if ((smf_refresh_instance(VS_INSTANCE_FMRI)) == -1) { - return (VS_ERR_SCF); - } + vs_engid_to_pgname(engid, pgname); - return (VS_ERR_NONE); + return (vs_scf_pg_delete(pgname)); } @@ -769,7 +749,6 @@ vs_scf_pg_create(const char *pgname, vs_prop_hd_t *prop_hd) { int rc; uint64_t propid; - uint64_t propids = prop_hd->vp_ids; vs_scfctx_t vsc; /* ensure that caller has authorization to refresh service */ @@ -795,23 +774,68 @@ vs_scf_pg_create(const char *pgname, vs_prop_hd_t *prop_hd) if ((propid & prop_hd->vp_all) && !(propid & prop_hd->vp_ids)) vs_default_value(prop_hd, propid); } - prop_hd->vp_ids = prop_hd->vp_all; - - - if ((propids & VS_PROPID_SE_HOST) == 0) - (void) strlcpy(prop_hd->vp_se.vep_host, pgname, MAXHOSTNAMELEN); + prop_hd->vp_ids = prop_hd->vp_all; prop_hd->vp_ids |= VS_PROPID_VALUE_AUTH; rc = vs_scf_values_set(pgname, prop_hd); if (rc != VS_ERR_NONE) - (void) vs_props_se_delete(pgname); + (void) vs_scf_pg_delete(pgname); return (rc); } /* + * vs_scf_pg_delete + */ +static int +vs_scf_pg_delete(const char *pgname) +{ + int rc; + vs_scfctx_t vsc; + + /* ensure that caller has authorization to refresh service */ + if ((rc = vs_checkauth(VS_ACTION_AUTH)) != VS_ERR_NONE) + return (rc); + + if (vs_scf_ctx_open(&vsc) != 0) { + vs_scf_ctx_close(&vsc); + return (VS_ERR_SCF); + } + + if (scf_instance_get_pg(vsc.vscf_inst, pgname, vsc.vscf_pgroup) == -1) { + vs_scf_ctx_close(&vsc); + rc = scf_error(); + if ((rc == SCF_ERROR_NOT_FOUND) || + (rc == SCF_ERROR_INVALID_ARGUMENT)) + return (VS_ERR_INVALID_SE); + else + return (VS_ERR_SCF); + } + + if (scf_pg_delete(vsc.vscf_pgroup) == -1) { + vs_scf_ctx_close(&vsc); + rc = scf_error(); + if ((rc == SCF_ERROR_NOT_FOUND) || + (rc == SCF_ERROR_INVALID_ARGUMENT)) + return (VS_ERR_INVALID_SE); + + return (VS_ERR_SCF); + } + + vs_scf_ctx_close(&vsc); + + /* Notify the daemon that things have changed */ + if ((smf_refresh_instance(VS_INSTANCE_FMRI)) == -1) { + return (VS_ERR_SCF); + } + + return (VS_ERR_NONE); +} + + +/* * vs_scf_values_set * * Sets property values in the repository. This is the single @@ -832,7 +856,6 @@ vs_scf_values_set(const char *pgname, vs_prop_hd_t *prop_hd) uint64_t propid; vs_scfctx_t vsc; - /* ensure that caller has authorization to refresh service */ if ((rc = vs_checkauth(VS_ACTION_AUTH)) != VS_ERR_NONE) return (rc); @@ -1321,41 +1344,44 @@ vs_statistics(vs_stats_t *stats) { int door_fd, rc = VS_ERR_NONE; vs_stats_req_t *req; - vs_stats_t *buf; + vs_stats_rsp_t *rsp; door_arg_t arg; if ((req = calloc(1, sizeof (vs_stats_req_t))) == NULL) return (VS_ERR_SYS); - if ((buf = calloc(1, sizeof (vs_stats_t))) == NULL) { + if ((rsp = calloc(1, sizeof (vs_stats_rsp_t))) == NULL) { free(req); return (VS_ERR_SYS); } if ((door_fd = open(VS_STATS_DOOR_NAME, O_RDONLY)) < 0) { free(req); - free(buf); + free(rsp); return (VS_ERR_DAEMON_COMM); } - *req = VS_STATS_GET; + req->vsr_magic = VS_STATS_DOOR_MAGIC; + req->vsr_id = VS_STATS_GET; arg.data_ptr = (char *)req; arg.data_size = sizeof (vs_stats_req_t); arg.desc_ptr = NULL; arg.desc_num = 0; - arg.rbuf = (char *)buf; - arg.rsize = sizeof (vs_stats_t); + arg.rbuf = (char *)rsp; + arg.rsize = sizeof (vs_stats_rsp_t); - if (door_call(door_fd, &arg) < 0) + if ((door_call(door_fd, &arg) < 0) || + (rsp->vsr_magic != VS_STATS_DOOR_MAGIC)) { rc = VS_ERR_DAEMON_COMM; - else - *stats = *buf; + } else { + *stats = rsp->vsr_stats; + } (void) close(door_fd); free(req); - free(buf); + free(rsp); return (rc); } @@ -1382,7 +1408,8 @@ vs_statistics_reset() return (VS_ERR_DAEMON_COMM); } - *req = VS_STATS_RESET; + req->vsr_magic = VS_STATS_DOOR_MAGIC; + req->vsr_id = VS_STATS_RESET; arg.data_ptr = (char *)req; arg.data_size = sizeof (vs_stats_req_t); @@ -1426,15 +1453,19 @@ vs_checkauth(char *auth) /* * vs_props_get_engines + * * On input, count specifies the maximum number of engine ids to * return. engids must be an array with count entries. * On return, count specifies the number of engine ids being * returned in engids. + * + * Caller is responsible for free'ing the engids allocated herein. */ static int -vs_props_get_engines(vs_engid_t *engids, int *count) +vs_props_get_engines(char *engids[], int *count) { - int i = 0; + int i, prefix_len; + char pgname[VS_PGNAME_ENGINE_LEN]; vs_scfctx_t vsc; @@ -1446,19 +1477,26 @@ vs_props_get_engines(vs_engid_t *engids, int *count) return (VS_ERR_SCF); } + for (i = 0; i < *count; i++) + engids[i] = NULL; + + i = 0; + prefix_len = sizeof (VS_PGNAME_ENGINE_PREFIX) - 1; + while ((i < VS_SE_MAX) && (scf_iter_next_pg(vsc.vscf_iter, vsc.vscf_pgroup) == 1)) { - if (scf_pg_get_name(vsc.vscf_pgroup, engids[i], - VS_SE_NAME_LEN) < 0) { + if (scf_pg_get_name(vsc.vscf_pgroup, pgname, + VS_PGNAME_ENGINE_LEN) < 0) { vs_scf_ctx_close(&vsc); return (VS_ERR_SCF); } - if (strcmp(engids[i], VS_PGNAME_GENERAL) == 0) - *engids[i] = 0; - else - if (++i == *count) - break; + if (strncmp(pgname, VS_PGNAME_ENGINE_PREFIX, prefix_len) == 0) { + if ((engids[i] = strdup(pgname + prefix_len)) != NULL) { + if (++i == *count) + break; + } + } } vs_scf_ctx_close(&vsc); @@ -1494,6 +1532,20 @@ vs_scf_pg_count(void) /* + * vs_engid_to_pgname + * + * To convert an engine id (engid) to a property group name (pgname), + * the engine id is prefixed with VS_PGNAME_ENGINE_PREFIX. + */ +static void +vs_engid_to_pgname(const char *engid, char pgname[VS_PGNAME_ENGINE_LEN]) +{ + (void) snprintf(pgname, VS_PGNAME_ENGINE_LEN, "%s%s", + VS_PGNAME_ENGINE_PREFIX, engid); +} + + +/* * vs_strtonum * * Converts a size string in the format into an integer. |
