コード例 #1
0
ファイル: topo_nic.c プロジェクト: drscream/illumos-joyent
int
_topo_init(topo_mod_t *mod, topo_version_t version)
{
	dladm_handle_t handle;

	if (getenv("TOPONICDEBUG") != NULL)
		topo_mod_setdebug(mod);

	topo_mod_dprintf(mod, "_mod_init: "
	    "initializing %s enumerator\n", NIC);

	if (version != NIC_VERSION) {
		return (-1);
	}

	if (dladm_open(&handle) != 0)
		return (-1);

	if (topo_mod_register(mod, &nic_mod, TOPO_VERSION) != 0) {
		dladm_close(handle);
		return (-1);
	}

	topo_mod_setspecific(mod, handle);

	return (0);
}
コード例 #2
0
ファイル: network_rcm.c プロジェクト: AlainODea/illumos-gate
/*
 * rcm_mod_fini()
 *
 *	Destroy the cache.
 */
int
rcm_mod_fini(void)
{
	free_cache();
	(void) mutex_destroy(&cache_lock);

	dladm_close(dld_handle);
	return (RCM_SUCCESS);
}
コード例 #3
0
static void
usage(void)
{
	(void) fprintf(stderr, "%s\n", gettext(usage_ermsg));

	/* close dladm handle if it was opened */
	if (handle != NULL)
		dladm_close(handle);

	exit(1);
}
コード例 #4
0
ファイル: topo_nic.c プロジェクト: drscream/illumos-joyent
void
_topo_fini(topo_mod_t *mod)
{
	dladm_handle_t handle;

	if ((handle = topo_mod_getspecific(mod)) == NULL)
		return;

	dladm_close(handle);
	topo_mod_setspecific(mod, NULL);
}
コード例 #5
0
ファイル: flowadm.c プロジェクト: CoryXie/opensolaris
int
main(int argc, char *argv[])
{
	int	i, arglen, cmdlen;
	cmd_t	*cmdp;
	dladm_status_t status;

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	progname = argv[0];

	if (argc < 2)
		usage();

	for (i = 0; i < sizeof (cmds) / sizeof (cmds[0]); i++) {
		cmdp = &cmds[i];
		arglen = strlen(argv[1]);
		cmdlen = strlen(cmdp->c_name);
		if ((arglen == cmdlen) && (strncmp(argv[1], cmdp->c_name,
		    cmdlen) == 0)) {
			/* Open the libdladm handle */
			if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) {
				die_dlerr(status,
				    "could not open /dev/dld");
			}

			cmdp->c_fn(argc - 1, &argv[1]);

			dladm_close(handle);
			exit(EXIT_SUCCESS);
		}
	}

	(void) fprintf(stderr, gettext("%s: unknown subcommand '%s'\n"),
	    progname, argv[1]);
	usage();

	return (0);
}
コード例 #6
0
/* PRINTFLIKE2 */
static void
die_dlerr(dladm_status_t err, const char *format, ...)
{
	va_list alist;
	char	errmsg[DLADM_STRSIZE];

	format = gettext(format);
	(void) fprintf(stderr, "%s: ", progname);

	va_start(alist, format);
	(void) vfprintf(stderr, format, alist);
	va_end(alist);
	(void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg));

	/* close dladm handle if it was opened */
	if (handle != NULL)
		dladm_close(handle);

	exit(EXIT_FAILURE);
}
コード例 #7
0
/* PRINTFLIKE1 */
static void
die(const char *format, ...)
{
	va_list alist;

	format = gettext(format);
	(void) fprintf(stderr, "%s: ", progname);

	va_start(alist, format);
	(void) vfprintf(stderr, format, alist);
	va_end(alist);

	(void) putc('\n', stderr);

	/* close dladm handle if it was opened */
	if (handle != NULL)
		dladm_close(handle);

	exit(EXIT_FAILURE);
}
コード例 #8
0
ファイル: libdlpi.c プロジェクト: apprisi/illumos-gate
/*ARGSUSED*/
void
dlpi_walk(dlpi_walkfunc_t *fn, void *arg, uint_t flags)
{
	struct i_dlpi_walklink_arg warg;
	struct dirent *d;
	DIR *dp;
	dladm_handle_t handle;

	warg.fn = fn;
	warg.arg = arg;

	if (flags & DLPI_DEVIPNET) {
		if ((dp = opendir("/dev/ipnet")) == NULL)
			return;

		while ((d = readdir(dp)) != NULL) {
			if (d->d_name[0] == '.')
				continue;

			if (warg.fn(d->d_name, warg.arg))
				break;
		}

		(void) closedir(dp);
	} else {
		/*
		 * Rather than have libdlpi take the libdladm handle,
		 * open the handle here.
		 */
		if (dladm_open(&handle) != DLADM_STATUS_OK)
			return;

		(void) dladm_walk(i_dlpi_walk_link, handle, &warg,
		    DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE,
		    DLADM_OPT_ACTIVE);

		dladm_close(handle);
	}
}
コード例 #9
0
ファイル: flowadm.c プロジェクト: CoryXie/opensolaris
static void
usage(void)
{
	(void) fprintf(stderr, gettext("usage: flowadm <subcommand>"
	    " <args>...\n"
	    "    add-flow       [-t] -l <link> -a <attr>=<value>[,...]\n"
	    "\t\t   [-p <prop>=<value>,...] <flow>\n"
	    "    remove-flow    [-t] {-l <link> | <flow>}\n"
	    "    show-flow      [-p] [-s [-i <interval>]] [-l <link>] "
	    "[<flow>]\n\n"
	    "    set-flowprop   [-t] -p <prop>=<value>[,...] <flow>\n"
	    "    reset-flowprop [-t] [-p <prop>,...] <flow>\n"
	    "    show-flowprop  [-cP] [-l <link>] [-p <prop>,...] "
	    "[<flow>]\n\n"
	    "    show-usage     [-a] [-d | -F <format>] "
	    "[-s <DD/MM/YYYY,HH:MM:SS>]\n"
	    "\t\t   [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> [<flow>]\n"));

	/* close dladm handle if it was opened */
	if (handle != NULL)
		dladm_close(handle);

	exit(1);
}
コード例 #10
0
ファイル: main.c プロジェクト: CoryXie/opensolaris
int
main(int argc, char *argv[])
{
    int c;
    int scan_lev;
    struct np_event *e;
    enum np_event_type etype;

    (void) setlocale(LC_ALL, "");
    (void) textdomain(TEXT_DOMAIN);

    shutting_down = B_FALSE;
    start_logging();
    syslog(LOG_INFO, "nwamd pid %d started", getpid());

    while ((c = getopt(argc, argv, "fs:")) != -1) {
        switch (c) {
        case 'f':
            fg = B_TRUE;
            break;
        case 's':
            scan_lev = atoi(optarg);
            if (scan_lev >= DLADM_WLAN_STRENGTH_VERY_WEAK &&
                    scan_lev <= DLADM_WLAN_STRENGTH_EXCELLENT) {
                wireless_scan_level = scan_lev;
            } else {
                syslog(LOG_ERR, "invalid signal "
                       "strength: %s", optarg);
            }
            break;
        default:
            syslog(LOG_ERR, "unrecognized option %c",
                   optopt);
            break;
        }
    }

    lookup_daemon_properties();

    /*
     * The dladm handle *must* be opened before privileges are dropped
     * by nwamd.  The device privilege requirements from
     * /etc/security/device_policy may not be loaded yet.  These are
     * loaded by svc:/system/filesystem/root, which comes online after
     * svc:/network/physical.
     */
    if (dladm_open(&dld_handle) != DLADM_STATUS_OK) {
        syslog(LOG_ERR, "failed to open dladm handle");
        exit(EXIT_FAILURE);
    }

    change_user_set_privs();

    if (!fg)
        daemonize();

    initialize_llp();

    init_signalhandling();

    initialize_wireless();

    lookup_zonename(zonename, sizeof (zonename));

    init_machine_mutex();

    initialize_interfaces();

    llp_parse_config();

    initialize_door();

    (void) start_event_collection();

    while ((e = np_queue_get_event()) != NULL) {

        etype = e->npe_type;
        syslog(LOG_INFO, "got event type %s", npe_type_str(etype));
        if (etype == EV_SHUTDOWN)
            terminate_door();
        if (pthread_mutex_lock(&machine_lock) != 0) {
            syslog(LOG_ERR, "mutex lock");
            exit(EXIT_FAILURE);
        }
        state_machine(e);
        (void) pthread_mutex_unlock(&machine_lock);
        free_event(e);
        if (etype == EV_SHUTDOWN)
            break;
    }
    syslog(LOG_DEBUG, "terminating routing and scanning threads");
    (void) pthread_cancel(routing);
    (void) pthread_join(routing, NULL);
    if (scan != 0) {
        (void) pthread_cancel(scan);
        (void) pthread_join(scan, NULL);
    }
    dladm_close(dld_handle);
    syslog(LOG_INFO, "nwamd shutting down");
    return (EXIT_SUCCESS);
}
コード例 #11
0
ファイル: libdlpi.c プロジェクト: apprisi/illumos-gate
/*
 * This function attempts to open a device under the following namespaces:
 *	/dev/ipnet	- if DLPI_DEVIPNET is specified
 *      /dev/net	- if a data-link with the specified name exists
 *	/dev		- if DLPI_DEVONLY is specified, or if there is no
 *			  data-link with the specified name (could be /dev/ip)
 *
 * In particular, if DLPI_DEVIPNET is not specified, this function is used to
 * open a data-link node, or "/dev/ip" node. It is usually be called firstly
 * with style1 being B_TRUE, and if that fails and the return value is not
 * DLPI_ENOTSTYLE2, the function will again be called with style1 being
 * B_FALSE (style-1 open attempt first, then style-2 open attempt).
 *
 * If DLPI_DEVONLY is specified, both attempt will try to open the /dev node
 * directly.
 *
 * Otherwise, for style-1 attempt, the function will try to open the style-1
 * /dev/net node, and perhaps fallback to open the style-1 /dev node if the
 * give name is not a data-link name (e.g., it is /dev/ip). Note that the
 * fallback and the subsequent style-2 attempt will not happen if:
 * 1. style-1 opening of the /dev/net node succeeds;
 * 2. style-1 opening of the /dev/net node fails with errno other than ENOENT,
 *    which means that the specific /dev/net node exist, but the attempt fails
 *    for some other reason;
 * 3. style-1 openning of the /dev/net fails with ENOENT, but the name is
 *    a known device name or its VLAN PPA hack name. (for example, assuming
 *    device bge0 is renamed to net0, opening /dev/net/bge1000 would return
 *    ENOENT, but we should not fallback to open /dev/bge1000 in this case,
 *    as VLAN 1 over the bge0 device should be named as net1000.
 *
 * DLPI_ENOTSTYLE2 will be returned in case 2 and 3 to indicate not to proceed
 * the second style-2 open attempt.
 */
static int
i_dlpi_open(const char *provider, int *fd, uint_t flags, boolean_t style1)
{
	char		path[MAXPATHLEN];
	int		oflags;

	errno = ENOENT;
	oflags = O_RDWR;
	if (flags & DLPI_EXCL)
		oflags |= O_EXCL;

	if (flags & DLPI_DEVIPNET) {
		(void) snprintf(path, sizeof (path), "/dev/ipnet/%s", provider);
		if ((*fd = open(path, oflags)) != -1)
			return (DLPI_SUCCESS);
		else
			return (errno == ENOENT ? DLPI_ENOLINK : DL_SYSERR);
	} else if (style1 && !(flags & DLPI_DEVONLY)) {
		char		driver[DLPI_LINKNAME_MAX];
		char		device[DLPI_LINKNAME_MAX];
		datalink_id_t	linkid;
		uint_t		ppa;
		dladm_handle_t	handle;

		/*
		 * This is not a valid style-1 name. It could be "ip" module
		 * for example. Fallback to open the /dev node.
		 */
		if (dlpi_parselink(provider, driver, &ppa) != DLPI_SUCCESS)
			goto fallback;

		(void) snprintf(path, sizeof (path), "/dev/net/%s", provider);
		if ((*fd = open(path, oflags)) != -1)
			return (DLPI_SUCCESS);

		/*
		 * We don't fallback to open the /dev node when it returns
		 * error codes other than ENOENT. In that case, DLPI_ENOTSTYLE2
		 * is returned to indicate not to continue the style-2 open.
		 */
		if (errno != ENOENT)
			return (DLPI_ENOTSTYLE2);

		/*
		 * We didn't find the /dev/net node. Then we check whether
		 * the given name is a device name or its VLAN PPA hack name
		 * of a known link. If the answer is yes, and this link
		 * supports vanity naming, then the link (or the VLAN) should
		 * also have its /dev/net node but perhaps with another vanity
		 * name (for example, when bge0 is renamed to net0). In this
		 * case, although attempt to open the /dev/net/<devname> fails,
		 * we should not fallback to open the /dev/<devname> node.
		 */
		(void) snprintf(device, DLPI_LINKNAME_MAX, "%s%d", driver,
		    ppa >= 1000 ? ppa % 1000 : ppa);

		/* open libdladm handle rather than taking it as input */
		if (dladm_open(&handle) != DLADM_STATUS_OK)
			goto fallback;

		if (dladm_dev2linkid(handle, device, &linkid) ==
		    DLADM_STATUS_OK) {
			dladm_phys_attr_t dpa;

			if ((dladm_phys_info(handle, linkid, &dpa,
			    DLADM_OPT_ACTIVE)) == DLADM_STATUS_OK &&
			    !dpa.dp_novanity) {
				dladm_close(handle);
				return (DLPI_ENOTSTYLE2);
			}
		}
		dladm_close(handle);
	}

fallback:
	(void) snprintf(path, sizeof (path), "/dev/%s", provider);
	if ((*fd = open(path, oflags)) != -1)
		return (DLPI_SUCCESS);

	return (errno == ENOENT ? DLPI_ENOLINK : DL_SYSERR);
}
コード例 #12
0
ファイル: datalink.cpp プロジェクト: danvatca/jsUnixApi
int dladm_finish() {
	dladm_close(g_handle);
	return 0;
}
コード例 #13
0
ファイル: main.c プロジェクト: 0xffea/illumos-gate
int
main(int argc, char *argv[])
{
	int c;			/* options character */
	int type = 0;		/* type of accounting */
	int modified = 0;	/* have we modified any properties? */
	acctconf_t ac;		/* current configuration */
	char *typestr = NULL;	/* type of accounting argument string */
	char *enabled = NULL;	/* enabled resources string */
	char *disabled = NULL;	/* disabled resources string */
	char *file = NULL;
	int Eflg = 0;
	int Dflg = 0;
	int rflg = 0;
	int sflg = 0;
	int xflg = 0;
	int optcnt = 0;
	int state;
	const char *fmri;	/* FMRI for this instance */
	int err = 0;

	setup_privs();

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);
	(void) setpname(argv[0]);

	for (; optind < argc; optind++) {
		while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
			switch (c) {
			case 'd':
				disabled = optarg;
				break;
			case 'e':
				enabled = optarg;
				break;
			case 'D':
				Dflg = 1;
				optcnt++;
				break;
			case 'E':
				Eflg = 1;
				optcnt++;
				break;
			case 'f':
				file = optarg;
				optcnt++;
				break;
			case 'r':
				rflg = 1;
				optcnt++;
				break;
			case 's':
				sflg = 1;
				optcnt++;
				break;
			case 'x':
				xflg = 1;
				optcnt++;
				break;
			case '?':
			default:
				usage();
			}
		}

		/*
		 * Permanently give up euid 0, egid 0 and privileges we
		 * don't need for the specified options.
		 */
		if (!(file || sflg)) {
			if (setreuid(getuid(), getuid()) == -1 ||
			    setregid(getgid(), getgid()) == -1)
				die(gettext("setreuid()/setregid() failed"));
			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
			    PRIV_FILE_DAC_WRITE, NULL);
		}
		if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
		    xflg))
			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
			    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);

		if (optind < argc) {
			if (typestr != NULL) {
				warn(gettext("illegal argument -- %s\n"),
				    argv[optind]);
				usage();
			} else {
				typestr = argv[optind];
			}
		}
	}
	if (typestr != NULL) {
		if (strcmp(typestr, "process") == 0 ||
		    strcmp(typestr, "proc") == 0)
			type |= AC_PROC;
		else if (strcmp(typestr, "task") == 0)
			type |= AC_TASK;
		else if (strcmp(typestr, "flow") == 0)
			type |= AC_FLOW;
		else if (strcmp(typestr, "net") == 0)
			type |= AC_NET;
		else {
			warn(gettext("unknown accounting type -- %s\n"),
			    typestr);
			usage();
		}
	} else
		type = AC_PROC | AC_TASK | AC_FLOW | AC_NET;

	/*
	 * Drop the DL config privilege if we are not working with
	 * net.
	 */
	if ((type & AC_NET) == 0) {
		(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
		    PRIV_SYS_DL_CONFIG, NULL);
	}
	/*
	 * check for invalid options
	 */
	if (optcnt > 1)
		usage();

	/*
	 * XXX For AC_NET, enabled/disabled should only be "basic" or
	 * "extended" - need to check it here.
	 */
	if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
		usage();

	if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
	    !typestr) {
		warn(gettext("accounting type must be specified\n"));
		usage();
	}

	if (rflg) {
		printgroups(type);
		return (E_SUCCESS);
	}

	/*
	 * If no arguments have been passed then just print out the current
	 * state and exit.
	 */
	if (!enabled && !disabled && !file &&
	    !Eflg && !rflg && !Dflg && !sflg && !xflg) {
		aconf_print(stdout, type);
		return (E_SUCCESS);
	}

	/* Open the libdladm handle */
	if (dladm_open(&dld_handle) != DLADM_STATUS_OK)
		die(gettext("failed to open dladm handle\n"));

	/*
	 * smf(5) start method.  The FMRI to operate on is retrieved from the
	 * SMF_FMRI environment variable that the restarter provides.
	 */
	if (sflg) {
		if ((fmri = getenv("SMF_FMRI")) != NULL) {
			int ret = aconf_setup(fmri);
			dladm_close(dld_handle);
			return (ret);
		}

		die(gettext("-s option should only be invoked by smf(5)\n"));
	}

	assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW ||
	    type == AC_NET);

	if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID)
		die(gettext("%s accounting cannot be configured in "
		    "non-global zones\n"), ac_type_name(type));

	fmri = aconf_type2fmri(type);
	if (aconf_scf_init(fmri) == -1)
		die(gettext("cannot connect to repository for %s\n"), fmri);

	/*
	 * Since the sys_acct the privilege allows use of acctctl() regardless
	 * of the accounting type, we check the smf(5) authorizations granted
	 * to the user to determine whether the user is allowed to change the
	 * configuration for this particular accounting type.
	 */
	if (!aconf_have_smf_auths())
		die(gettext("insufficient authorization to change %s extended "
		    "accounting configuration\n"), ac_type_name(type));

	if (xflg) {
		/*
		 * Turn off the specified accounting and close its file
		 */

		/*
		 * Stop net logging before turning it off so that the last
		 * set of logs can be written.
		 */
		if (type & AC_NET) {
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_stop_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to stop logging network "
				    "information, error %d\n"), errno);
			}
		}
		state = AC_OFF;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot disable %s accounting"),
			    ac_type_name(type));
		if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
			die(gettext("cannot close %s accounting file\n"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_FILE);
		modified++;
	}

	if (enabled || disabled) {
		char *tracked, *untracked;
		ac_res_t *buf;

		/*
		 * Enable/disable resources
		 */
		if ((buf = malloc(AC_BUFSIZE)) == NULL)
			die(gettext("not enough memory\n"));
		(void) memset(buf, 0, AC_BUFSIZE);
		if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
			free(buf);
			die(gettext("cannot obtain list of resources\n"));
		}
		if (disabled) {
			/*
			 * Stop net logging before turning it off so that the
			 * last set of logs can be written.
			 */
			if (type & AC_NET) {
				(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
				    PRIV_SYS_DL_CONFIG, NULL);
				err = dladm_stop_usagelog(dld_handle,
				    strcmp(disabled, "basic") == 0 ?
				    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW);
				(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
				    PRIV_SYS_DL_CONFIG, NULL);
				if (err != DLADM_STATUS_OK) {
					die(gettext("failed to stop logging "
					    "network information, error %d\n"),
					    errno);
				}
			}
			str2buf(buf, disabled, AC_OFF, type);
		} else if (enabled) {
			str2buf(buf, enabled, AC_ON, type);
		}
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
			free(buf);
			die(gettext("cannot enable/disable %s accounting "
			    "resources\n"), ac_type_name(type));
		}
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
		untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
		if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_TRACKED);
		if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_UNTRACKED);
		free(tracked);
		free(untracked);
		free(buf);
		modified++;
	}

	if (file) {
		/*
		 * Open new accounting file
		 */
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (open_exacct_file(file, type) == -1) {
			dladm_close(dld_handle);
			exit(E_ERROR);
		}
		if (aconf_set_string(AC_PROP_FILE, file) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_FILE);
		state = AC_ON;

		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot enable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}

	/*
	 * Let's get network logging started. We do this after turning on
	 * accounting and opening the file so that we can start writing
	 * immediately.
	 */
	if (enabled && (type & AC_NET)) {
		/*
		 * Default logging interval for AC_NET is
		 * ACCTADM_NET_LOG_INTERVAL.
		 */
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
		    PRIV_SYS_DL_CONFIG, NULL);
		err = dladm_start_usagelog(dld_handle,
		    strcmp(enabled, "basic") == 0 ?
		    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW,
		    ACCTADM_NET_LOG_INTERVAL);
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
		    PRIV_SYS_DL_CONFIG, NULL);
		if (err != DLADM_STATUS_OK) {
			die(gettext("failed to start logging "
			    "network information, error %d\n"),
			    errno);
		}
	}

	if (Dflg) {
		/*
		 * Disable accounting
		 */

		/*
		 * Stop net logging before turning it off so that the last
		 * set of logs can be written.
		 */
		if (type & AC_NET) {
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_stop_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to stop logging "
				    "network information, error %d\n"), errno);
			}
		}
		state = AC_OFF;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot disable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}

	if (Eflg) {
		/*
		 * Enable accounting
		 */

		/*
		 * Let's get network logging started.
		 */
		if (type & AC_NET) {
			/*
			 * Default logging interval for AC_NET is
			 * ACCTADM_NET_LOG_INTERVAL.
			 */
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_start_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to start logging "
				    "network information, error %d\n"), errno);
			}
		}
		state = AC_ON;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot enable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}
	(void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);

	if (modified) {
		char *smf_state;

		if (aconf_save() == -1)
			die(gettext("cannot save %s accounting "
			    "configuration\n"), ac_type_name(type));

		/*
		 * Enable or disable the instance depending on the effective
		 * configuration.  If the effective configuration results in
		 * extended accounting being 'on', the instance is enabled so
		 * the configuration is applied at the next boot.
		 */
		smf_state = smf_get_state(fmri);
		aconf_init(&ac, type);

		if (ac.state == AC_ON ||
		    strcmp(ac.file, AC_STR_NONE) != 0 ||
		    strcmp(ac.tracked, AC_STR_NONE) != 0) {
			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
				if (smf_enable_instance(fmri, 0) == -1)
					die(gettext("cannot enable %s\n"),
					    fmri);
		} else {
			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
				if (smf_disable_instance(fmri, 0) == -1)
					die(gettext("cannot disable %s\n"),
					    fmri);
		}
		free(smf_state);
	}
	aconf_scf_fini();
	dladm_close(dld_handle);
	return (E_SUCCESS);
}
コード例 #14
0
int
main(int argc, char *argv[])
{
	dladm_status_t 		status;
	int			option;
	boolean_t		r_arg = B_FALSE;
	boolean_t		t_arg = B_FALSE;
	boolean_t		p_arg = B_FALSE;
	boolean_t		i_arg = B_FALSE;
	boolean_t		o_arg = B_FALSE;
	boolean_t		u_arg = B_FALSE;
	boolean_t		A_arg = B_FALSE;
	boolean_t		flow_arg = B_FALSE;
	datalink_id_t		linkid = DATALINK_ALL_LINKID;
	char			linkname[MAXLINKNAMELEN];
	char			flowname[MAXFLOWNAMELEN];
	uint32_t		interval = 0;
	char			unit = '\0';
	show_flow_state_t	state;
	char			*fields_str = NULL;
	char			*o_fields_str = NULL;
	char			*zonename = NULL;

	char			*total_stat_fields =
	    "flow,ipkts,rbytes,ierrs,opkts,obytes,oerrs";
	char			*rx_stat_fields =
	    "flow,ipkts,rbytes,ierrs";
	char			*tx_stat_fields =
	    "flow,opkts,obytes,oerrs";

	ofmt_handle_t		ofmt;
	ofmt_status_t		oferr;
	uint_t			ofmtflags = OFMT_RIGHTJUST;

	dladm_flow_attr_t	attr;

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	(void) textdomain(TEXT_DOMAIN);

	progname = argv[0];

	/* Open the libdladm handle */
	if ((status = dladm_open(&handle)) != DLADM_STATUS_OK)
		die_dlerr(status, "could not open /dev/dld");

	linkname[0] = '\0';
	bzero(&state, sizeof (state));

	opterr = 0;
	while ((option = getopt_long(argc, argv, ":rtApi:o:u:l:hz:",
	    NULL, NULL)) != -1) {
		switch (option) {
		case 'r':
			if (r_arg)
				die_optdup(option);

			r_arg = B_TRUE;
			break;
		case 't':
			if (t_arg)
				die_optdup(option);

			t_arg = B_TRUE;
			break;
		case 'A':
			if (A_arg)
				die_optdup(option);

			A_arg = B_TRUE;
			break;
		case 'p':
			if (p_arg)
				die_optdup(option);

			p_arg = B_TRUE;
			break;
		case 'i':
			if (i_arg)
				die_optdup(option);

			i_arg = B_TRUE;
			if (!dladm_str2interval(optarg, &interval))
				die("invalid interval value '%s'", optarg);
			break;
		case 'o':
			o_arg = B_TRUE;
			o_fields_str = optarg;
			break;
		case 'u':
			if (u_arg)
				die_optdup(option);

			u_arg = B_TRUE;
			if (!flowstat_unit(optarg, &unit))
				die("invalid unit value '%s',"
				    "unit must be R|K|M|G|T|P", optarg);
			break;
		case 'l':
			if (strlcpy(linkname, optarg, MAXLINKNAMELEN)
			    >= MAXLINKNAMELEN)
				die("link name too long\n");
			break;
		case 'h':
			if (r_arg || t_arg || p_arg || o_arg || u_arg ||
			    i_arg || A_arg) {
				die("the option -h is not compatible with "
				    "-r, -t, -p, -o, -u, -i, -A");
			}
			do_show_history(argc, argv);
			return (0);
			break;
		case 'z':
			zonename = optarg;
			break;
		default:
			die_opterr(optopt, option, usage_ermsg);
			break;
		}
	}

	if (r_arg && t_arg)
		die("the option -t and -r are not compatible");

	if (u_arg && p_arg)
		die("the option -u and -p are not compatible");

	if (p_arg && !o_arg)
		die("-p requires -o");

	if (p_arg && strcasecmp(o_fields_str, "all") == 0)
		die("\"-o all\" is invalid with -p");

	if (A_arg &&
	    (r_arg || t_arg || p_arg || o_arg || u_arg || i_arg))
		die("the option -A is not compatible with "
		    "-r, -t, -p, -o, -u, -i");

	if (linkname[0] != '\0') {
		if (dladm_zname2info(handle, zonename, linkname, &linkid, NULL,
		    NULL, NULL) != DLADM_STATUS_OK)
			die("invalid link '%s'", linkname);
	}

	/* get flow name (optional last argument) */
	if (optind == (argc-1)) {
		if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN)
		    >= MAXFLOWNAMELEN)
			die("flow name too long");
		flow_arg = B_TRUE;
	} else if (optind != argc) {
		usage();
	}

	if (flow_arg &&
	    dladm_flow_info(handle, flowname, &attr) != DLADM_STATUS_OK)
		die("invalid flow %s", flowname);

	if (A_arg) {
		dump_all_flow_stats(&attr, &state, linkid, flow_arg);
		return (0);
	}

	state.fs_unit = unit;
	state.fs_parsable = p_arg;

	if (state.fs_parsable)
		ofmtflags |= OFMT_PARSABLE;

	if (r_arg)
		fields_str = rx_stat_fields;
	else if (t_arg)
		fields_str = tx_stat_fields;
	else
		fields_str = total_stat_fields;

	if (o_arg) {
		fields_str = (strcasecmp(o_fields_str, "all") == 0) ?
		    fields_str : o_fields_str;
	}

	oferr = ofmt_open(fields_str, flow_s_fields, ofmtflags, 0, &ofmt);
	ofmt_check(oferr, state.fs_parsable, ofmt, die, warn);
	state.fs_ofmt = ofmt;

	for (;;) {
		/* Show stats for named flow */
		if (flow_arg)  {
			(void) query_flow_stats(handle, &attr, &state);

		/* Show stats for flows on one link */
		} else if (linkid != DATALINK_INVALID_LINKID) {
			(void) dladm_walk_flow(query_flow_stats, handle, linkid,
			    &state, B_FALSE);

		/* Show stats for all flows on all links */
		} else {
			(void) dladm_walk_datalink_id(query_link_flow_stats,
			    handle, &state, DATALINK_CLASS_ALL,
			    DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
		}

		if (interval == 0)
			break;

		(void) fflush(stdout);
		cleanup_removed_flows(&state);
		(void) sleep(interval);
	}
	ofmt_close(ofmt);

	dladm_close(handle);
	return (0);
}
コード例 #15
0
ファイル: flowadm.c プロジェクト: CoryXie/opensolaris
static void
set_flowprop(int argc, char **argv, boolean_t reset)
{
	int			i, option;
	char			errmsg[DLADM_STRSIZE];
	const char		*flow = NULL;
	char			propstr[DLADM_STRSIZE];
	dladm_arg_list_t	*proplist = NULL;
	boolean_t		temp = B_FALSE;
	dladm_status_t		status = DLADM_STATUS_OK;

	opterr = 0;
	bzero(propstr, DLADM_STRSIZE);

	while ((option = getopt_long(argc, argv, ":p:R:t",
	    prop_longopts, NULL)) != -1) {
		switch (option) {
		case 'p':
			(void) strlcat(propstr, optarg, DLADM_STRSIZE);
			if (strlcat(propstr, ",", DLADM_STRSIZE) >=
			    DLADM_STRSIZE)
				die("property list too long '%s'", propstr);
			break;
		case 't':
			temp = B_TRUE;
			break;
		case 'R':
			status = dladm_set_rootdir(optarg);
			if (status != DLADM_STATUS_OK) {
				die_dlerr(status, "invalid directory "
				    "specified");
			}
			break;
		default:
			die_opterr(optopt, option);
			break;
		}
	}

	if (optind == (argc - 1)) {
		if (strlen(argv[optind]) >= MAXFLOWNAMELEN)
			die("flow name too long");
		flow = argv[optind];
	} else if (optind != argc) {
		usage();
	}
	if (flow == NULL)
		die("flow name must be specified");

	if (dladm_parse_flow_props(propstr, &proplist, reset)
	    != DLADM_STATUS_OK)
		die("invalid flow property specified");

	if (proplist == NULL) {
		char *errprop;

		if (!reset)
			die("flow property must be specified");

		status = dladm_set_flowprop(handle, flow, NULL, NULL, 0,
		    DLADM_OPT_ACTIVE, &errprop);
		if (status != DLADM_STATUS_OK) {
			warn_dlerr(status, "cannot reset flow property '%s' "
			    "on '%s'", errprop, flow);
		}
		if (!temp) {
			dladm_status_t	s;

			s = set_flowprop_persist(flow, NULL, NULL, 0, reset);
			if (s != DLADM_STATUS_OK)
				status = s;
		}
		goto done;
	}

	for (i = 0; i < proplist->al_count; i++) {
		dladm_arg_info_t	*aip = &proplist->al_info[i];
		char		**val;
		uint_t		count;
		dladm_status_t	s;

		if (reset) {
			val = NULL;
			count = 0;
		} else {
			val = aip->ai_val;
			count = aip->ai_count;
			if (count == 0) {
				warn("no value specified for '%s'",
				    aip->ai_name);
				status = DLADM_STATUS_BADARG;
				continue;
			}
		}
		s = dladm_set_flowprop(handle, flow, aip->ai_name, val, count,
		    DLADM_OPT_ACTIVE, NULL);
		if (s == DLADM_STATUS_OK) {
			if (!temp) {
				s = set_flowprop_persist(flow,
				    aip->ai_name, val, count, reset);
				if (s != DLADM_STATUS_OK)
					status = s;
			}
			continue;
		}
		status = s;
		switch (s) {
		case DLADM_STATUS_NOTFOUND:
			warn("invalid flow property '%s'", aip->ai_name);
			break;
		case DLADM_STATUS_BADVAL: {
			int		j;
			char		*ptr, *lim;
			char		**propvals = NULL;
			uint_t		valcnt = DLADM_MAX_PROP_VALCNT;

			ptr = malloc((sizeof (char *) +
			    DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT +
			    MAX_PROP_LINE);

			if (ptr == NULL)
				die("insufficient memory");
			propvals = (char **)(void *)ptr;

			for (j = 0; j < DLADM_MAX_PROP_VALCNT; j++) {
				propvals[j] = ptr + sizeof (char *) *
				    DLADM_MAX_PROP_VALCNT +
				    j * DLADM_PROP_VAL_MAX;
			}
			s = dladm_get_flowprop(handle, flow,
			    DLADM_PROP_VAL_MODIFIABLE, aip->ai_name, propvals,
			    &valcnt);

			ptr = errmsg;
			lim = ptr + DLADM_STRSIZE;
			*ptr = '\0';
			for (j = 0; j < valcnt && s == DLADM_STATUS_OK; j++) {
				ptr += snprintf(ptr, lim - ptr, "%s,",
				    propvals[j]);
				if (ptr >= lim)
					break;
			}
			if (ptr > errmsg) {
				*(ptr - 1) = '\0';
				warn("flow property '%s' must be one of: %s",
				    aip->ai_name, errmsg);
			} else
				warn("%s is an invalid value for "
				    "flow property %s", *val, aip->ai_name);
			free(propvals);
			break;
		}
		default:
			if (reset) {
				warn_dlerr(status, "cannot reset flow property "
				    "'%s' on '%s'", aip->ai_name, flow);
			} else {
				warn_dlerr(status, "cannot set flow property "
				    "'%s' on '%s'", aip->ai_name, flow);
			}
			break;
		}
	}
done:
	dladm_free_props(proplist);
	if (status != DLADM_STATUS_OK) {
		dladm_close(handle);
		exit(EXIT_FAILURE);
	}
}
コード例 #16
0
/* ARGSUSED */
static void
do_show_history(int argc, char *argv[])
{
	char			*file = NULL;
	int			opt;
	dladm_status_t		status;
	boolean_t		d_arg = B_FALSE;
	char			*stime = NULL;
	char			*etime = NULL;
	char			*resource = NULL;
	show_history_state_t	state;
	boolean_t		o_arg = B_FALSE;
	boolean_t		F_arg = B_FALSE;
	char			*fields_str = NULL;
	char			*formatspec_str = NULL;
	char			*all_fields =
	    "flow,duration,ipackets,rbytes,opackets,obytes,bandwidth";
	char			*all_l_fields =
	    "flow,start,end,rbytes,obytes,bandwidth";
	ofmt_handle_t		ofmt;
	ofmt_status_t		oferr;
	uint_t			ofmtflags = 0;

	bzero(&state, sizeof (show_history_state_t));
	state.us_parsable = B_FALSE;
	state.us_printheader = B_FALSE;
	state.us_plot = B_FALSE;
	state.us_first = B_TRUE;

	while ((opt = getopt(argc, argv, "das:e:o:f:F:")) != -1) {
		switch (opt) {
		case 'd':
			d_arg = B_TRUE;
			break;
		case 'a':
			state.us_showall = B_TRUE;
			break;
		case 'f':
			file = optarg;
			break;
		case 's':
			stime = optarg;
			break;
		case 'e':
			etime = optarg;
			break;
		case 'o':
			o_arg = B_TRUE;
			fields_str = optarg;
			break;
		case 'F':
			state.us_plot = F_arg = B_TRUE;
			formatspec_str = optarg;
			break;
		default:
			die_opterr(optopt, opt, usage_ermsg);
		}
	}

	if (file == NULL)
		die("-h requires a file");

	if (optind == (argc-1)) {
		dladm_flow_attr_t	attr;

		resource = argv[optind];
		if (!state.us_showall &&
		    dladm_flow_info(handle, resource, &attr) !=
		    DLADM_STATUS_OK) {
			die("invalid flow: '%s'", resource);
		}
	}

	if (state.us_parsable)
		ofmtflags |= OFMT_PARSABLE;
	if (resource == NULL && stime == NULL && etime == NULL) {
		if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0))
			fields_str = all_fields;
		oferr = ofmt_open(fields_str, history_fields, ofmtflags,
		    0, &ofmt);
	} else {
		if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0))
			fields_str = all_l_fields;
		oferr = ofmt_open(fields_str, history_l_fields, ofmtflags,
		    0, &ofmt);
	}

	ofmt_check(oferr, state.us_parsable, ofmt, die, warn);
	state.us_ofmt = ofmt;

	if (F_arg && d_arg)
		die("incompatible -d and -F options");

	if (F_arg && !valid_formatspec(formatspec_str))
		die("Format specifier %s not supported", formatspec_str);

	if (d_arg) {
		/* Print log dates */
		status = dladm_usage_dates(show_history_date,
		    DLADM_LOGTYPE_FLOW, file, resource, &state);
	} else if (resource == NULL && stime == NULL && etime == NULL &&
	    !F_arg) {
		/* Print summary */
		status = dladm_usage_summary(show_history_res,
		    DLADM_LOGTYPE_FLOW, file, &state);
	} else if (resource != NULL) {
		/* Print log entries for named resource */
		status = dladm_walk_usage_res(show_history_time,
		    DLADM_LOGTYPE_FLOW, file, resource, stime, etime, &state);
	} else {
		/* Print time and information for each flow */
		status = dladm_walk_usage_time(show_history_time,
		    DLADM_LOGTYPE_FLOW, file, stime, etime, &state);
	}

	ofmt_close(ofmt);
	if (status != DLADM_STATUS_OK)
		die_dlerr(status, "-h");
	dladm_close(handle);
}
コード例 #17
0
ファイル: aoeadm.c プロジェクト: Nooteboom/illumos-nexenta
static int
aoeadm_list_ports(int argc, char **argv)
{
	AOE_STATUS	ret;
	aoe_port_list_t	*portlist = NULL;
	char		c;
	dladm_handle_t	handle;
	int		i;
	int		portid = -1;
	int		verbose = 0;
	uint32_t	nports;

	while ((c = getopt(argc, argv, "v")) != -1) {
		switch (c) {
		case 'v':
			verbose = 1;
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (argc == 1) {
		errno = 0;
		portid = strtol(argv[0], (char **)NULL, 10);
		if (errno != 0 || portid < 0)
			usage();
	}

	ret = aoe_get_port_list(&nports, &portlist);

	if (ret != AOE_STATUS_OK) {
		(void) fprintf(stderr, _("Failed to list ports: %s\n"),
		    aoe_strerror(ret));
		return (ret);
	}

	if (nports == 0) {
		free(portlist);
		return (0);
	}

	if (dladm_open(&handle) != DLADM_STATUS_OK)
		handle = NULL;

	for (i = 0; i < nports; i++) {
		aoe_port_instance_t *pi = &portlist->ports[i];
		char		linknames[AOE_MAX_MACOBJ * MAXLINKNAMELEN];
		int		j;

		if (portid >= 0 && pi->api_port_id != portid)
			continue;

		if ((pi->api_port_type == AOE_CLIENT_INITIATOR &&
		    strcmp(cmdname, "list-target") == 0) ||
		    (pi->api_port_type == AOE_CLIENT_TARGET &&
		    strcmp(cmdname, "list-initiator") == 0))
			continue;

		/* Convert linkid to interface name */
		for (j = 0; j < pi->api_mac_cnt; j++) {
			aoe_mac_instance_t *mi = &pi->api_mac[j];
			char	*linkname = linknames + j * MAXLINKNAMELEN;

			if (handle == NULL ||
			    dladm_datalink_id2info(handle, mi->ami_mac_linkid,
			    NULL, NULL, NULL, linkname, MAXLINKNAMELEN - 1) !=
			    DLADM_STATUS_OK)
				(void) strcpy(linkname, "<unknown>");
		}

		print_port_info(pi, linknames, verbose);

		if (portid >= 0) {
			if (handle != NULL)
				dladm_close(handle);
			free(portlist);
			return (0);
		}
	}

	if (handle != NULL)
		dladm_close(handle);
	free(portlist);

	return (portid >= 0 ? 1 : 0);
}