X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=7819002d04472b3f67cfd2501f3f87deb0cf251c;hb=a74934bae19f96845f7af4b95a8fae5c2f860747;hp=150a2dfe4675bfbfaf90d5e30b51d54ab6eb284d;hpb=ffe600149a7608221985751e1bf293234bf2545c;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 150a2dfe4..7819002d0 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -28,6 +28,7 @@ #include "channel.h" #include "consumer.h" #include "event.h" +#include "health.h" #include "kernel.h" #include "kernel-consumer.h" #include "lttng-sessiond.h" @@ -38,12 +39,11 @@ /* * Used to keep a unique index for each relayd socket created where this value * is associated with streams on the consumer so it can match the right relayd - * to send to. - * - * This value should be incremented atomically for safety purposes and future - * possible concurrent access. + * to send to. It must be accessed with the relayd_net_seq_idx_lock + * held. */ -static unsigned int relayd_net_seq_idx; +static pthread_mutex_t relayd_net_seq_idx_lock = PTHREAD_MUTEX_INITIALIZER; +static uint64_t relayd_net_seq_idx; /* * Create a session path used by list_lttng_sessions for the case that the @@ -306,8 +306,12 @@ static int list_lttng_kernel_events(char *channel_name, case LTTNG_KERNEL_TRACEPOINT: (*events)[i].type = LTTNG_EVENT_TRACEPOINT; break; - case LTTNG_KERNEL_KPROBE: case LTTNG_KERNEL_KRETPROBE: + (*events)[i].type = LTTNG_EVENT_FUNCTION; + memcpy(&(*events)[i].attr.probe, &event->event->u.kprobe, + sizeof(struct lttng_kernel_kprobe)); + break; + case LTTNG_KERNEL_KPROBE: (*events)[i].type = LTTNG_EVENT_PROBE; memcpy(&(*events)[i].attr.probe, &event->event->u.kprobe, sizeof(struct lttng_kernel_kprobe)); @@ -376,12 +380,24 @@ static int add_uri_to_consumer(struct consumer_output *consumer, case LTTNG_DST_IPV6: DBG2("Setting network URI to consumer"); + if (consumer->type == CONSUMER_DST_NET) { + if ((uri->stype == LTTNG_STREAM_CONTROL && + consumer->dst.net.control_isset) || + (uri->stype == LTTNG_STREAM_DATA && + consumer->dst.net.data_isset)) { + ret = LTTNG_ERR_URL_EXIST; + goto error; + } + } else { + memset(&consumer->dst.net, 0, sizeof(consumer->dst.net)); + } + consumer->type = CONSUMER_DST_NET; /* Set URI into consumer output object */ ret = consumer_set_network_uri(consumer, uri); if (ret < 0) { - ret = LTTNG_ERR_FATAL; + ret = -ret; goto error; } else if (ret == 1) { /* @@ -422,6 +438,8 @@ static int add_uri_to_consumer(struct consumer_output *consumer, break; } + ret = LTTNG_OK; + error: return ret; } @@ -466,22 +484,15 @@ error: * On success, the relayd_sock pointer is set to the created socket. * Else, it's stays untouched and a lttcomm error code is returned. */ -static int create_connect_relayd(struct consumer_output *output, - const char *session_name, struct lttng_uri *uri, - struct lttcomm_sock **relayd_sock) +static int create_connect_relayd(struct lttng_uri *uri, + struct lttcomm_relayd_sock **relayd_sock) { int ret; - struct lttcomm_sock *sock; + struct lttcomm_relayd_sock *rsock; - /* Create socket object from URI */ - sock = lttcomm_alloc_sock_from_uri(uri); - if (sock == NULL) { - ret = LTTNG_ERR_FATAL; - goto error; - } - - ret = lttcomm_create_sock(sock); - if (ret < 0) { + rsock = lttcomm_alloc_relayd_sock(uri, RELAYD_VERSION_COMM_MAJOR, + RELAYD_VERSION_COMM_MINOR); + if (!rsock) { ret = LTTNG_ERR_FATAL; goto error; } @@ -492,7 +503,7 @@ static int create_connect_relayd(struct consumer_output *output, * state to be in poll execution. */ health_poll_entry(); - ret = relayd_connect(sock); + ret = relayd_connect(rsock); health_poll_exit(); if (ret < 0) { ERR("Unable to reach lttng-relayd"); @@ -505,8 +516,7 @@ static int create_connect_relayd(struct consumer_output *output, DBG3("Creating relayd stream socket from URI"); /* Check relayd version */ - ret = relayd_version_check(sock, RELAYD_VERSION_COMM_MAJOR, - RELAYD_VERSION_COMM_MINOR); + ret = relayd_version_check(rsock); if (ret < 0) { ret = LTTNG_ERR_RELAYD_VERSION_FAIL; goto close_sock; @@ -520,18 +530,15 @@ static int create_connect_relayd(struct consumer_output *output, goto close_sock; } - *relayd_sock = sock; + *relayd_sock = rsock; return LTTNG_OK; close_sock: - if (sock) { - (void) relayd_close(sock); - } + /* The returned value is not useful since we are on an error path. */ + (void) relayd_close(rsock); free_sock: - if (sock) { - lttcomm_destroy_sock(sock); - } + free(rsock); error: return ret; } @@ -544,13 +551,14 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session, struct consumer_socket *consumer_sock) { int ret; - struct lttcomm_sock *sock = NULL; + struct lttcomm_relayd_sock *rsock = NULL; /* Connect to relayd and make version check if uri is the control. */ - ret = create_connect_relayd(consumer, session->name, relayd_uri, &sock); + ret = create_connect_relayd(relayd_uri, &rsock); if (ret != LTTNG_OK) { - goto close_sock; + goto error; } + assert(rsock); /* If the control socket is connected, network session is ready */ if (relayd_uri->stype == LTTNG_STREAM_CONTROL) { @@ -558,20 +566,20 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session, } /* Set the network sequence index if not set. */ - if (consumer->net_seq_index == -1) { + if (consumer->net_seq_index == (uint64_t) -1ULL) { + pthread_mutex_lock(&relayd_net_seq_idx_lock); /* * Increment net_seq_idx because we are about to transfer the * new relayd socket to the consumer. + * Assign unique key so the consumer can match streams. */ - uatomic_inc(&relayd_net_seq_idx); - /* Assign unique key so the consumer can match streams */ - uatomic_set(&consumer->net_seq_index, - uatomic_read(&relayd_net_seq_idx)); + consumer->net_seq_index = ++relayd_net_seq_idx; + pthread_mutex_unlock(&relayd_net_seq_idx_lock); } /* Send relayd socket to consumer. */ - ret = consumer_send_relayd_socket(consumer_sock, sock, - consumer, relayd_uri->stype, session->id); + ret = consumer_send_relayd_socket(consumer_sock, rsock, consumer, + relayd_uri->stype, session->id); if (ret < 0) { ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL; goto close_sock; @@ -592,11 +600,10 @@ static int send_consumer_relayd_socket(int domain, struct ltt_session *session, */ close_sock: - if (sock) { - (void) relayd_close(sock); - lttcomm_destroy_sock(sock); - } + (void) relayd_close(rsock); + free(rsock); +error: if (ret != LTTNG_OK) { /* * On error, nullify the consumer sequence index so streams are not @@ -604,7 +611,6 @@ close_sock: */ uatomic_set(&consumer->net_seq_index, -1); } - return ret; } @@ -662,7 +668,7 @@ int cmd_setup_relayd(struct ltt_session *session) usess = session->ust_session; ksess = session->kernel_session; - DBG2("Setting relayd for session %s", session->name); + DBG("Setting relayd for session %s", session->name); rcu_read_lock(); @@ -809,7 +815,7 @@ int cmd_disable_channel(struct ltt_session *session, int domain, goto error; } - ret = channel_ust_disable(usess, domain, uchan); + ret = channel_ust_disable(usess, uchan); if (ret != LTTNG_OK) { goto error; } @@ -838,7 +844,7 @@ error: * The wpipe arguments is used as a notifier for the kernel thread. */ int cmd_enable_channel(struct ltt_session *session, - int domain, struct lttng_channel *attr, int wpipe) + struct lttng_domain *domain, struct lttng_channel *attr, int wpipe) { int ret; struct ltt_ust_session *usess = session->ust_session; @@ -846,12 +852,13 @@ int cmd_enable_channel(struct ltt_session *session, assert(session); assert(attr); + assert(domain); DBG("Enabling channel %s for session %s", attr->name, session->name); rcu_read_lock(); - switch (domain) { + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { struct ltt_kernel_channel *kchan; @@ -891,9 +898,9 @@ int cmd_enable_channel(struct ltt_session *session, uchan = trace_ust_find_channel_by_name(chan_ht, attr->name); if (uchan == NULL) { - ret = channel_ust_create(usess, domain, attr); + ret = channel_ust_create(usess, attr, domain->buf_type); } else { - ret = channel_ust_enable(usess, domain, uchan); + ret = channel_ust_enable(usess, uchan); } /* Start the UST session if the session was already started. */ @@ -908,11 +915,6 @@ int cmd_enable_channel(struct ltt_session *session, } break; } -#if 0 - case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN: - case LTTNG_DOMAIN_UST_EXEC_NAME: - case LTTNG_DOMAIN_UST_PID: -#endif default: ret = LTTNG_ERR_UNKNOWN_DOMAIN; goto error; @@ -970,7 +972,7 @@ int cmd_disable_event(struct ltt_session *session, int domain, goto error; } - ret = event_ust_disable_tracepoint(usess, domain, uchan, event_name); + ret = event_ust_disable_tracepoint(usess, uchan, event_name); if (ret != LTTNG_OK) { goto error; } @@ -1042,7 +1044,7 @@ int cmd_disable_event_all(struct ltt_session *session, int domain, goto error; } - ret = event_ust_disable_all_tracepoints(usess, domain, uchan); + ret = event_ust_disable_all_tracepoints(usess, uchan); if (ret != 0) { goto error; } @@ -1110,7 +1112,7 @@ int cmd_add_context(struct ltt_session *session, int domain, goto error; } - ret = channel_ust_create(usess, domain, attr); + ret = channel_ust_create(usess, attr, usess->buffer_type); if (ret != LTTNG_OK) { free(attr); goto error; @@ -1143,7 +1145,7 @@ error: /* * Command LTTNG_ENABLE_EVENT processed by the client thread. */ -int cmd_enable_event(struct ltt_session *session, int domain, +int cmd_enable_event(struct ltt_session *session, struct lttng_domain *domain, char *channel_name, struct lttng_event *event, struct lttng_filter_bytecode *filter, int wpipe) { @@ -1156,7 +1158,7 @@ int cmd_enable_event(struct ltt_session *session, int domain, rcu_read_lock(); - switch (domain) { + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { struct ltt_kernel_channel *kchan; @@ -1164,7 +1166,7 @@ int cmd_enable_event(struct ltt_session *session, int domain, kchan = trace_kernel_get_channel_by_name(channel_name, session->kernel_session); if (kchan == NULL) { - attr = channel_new_default_attr(domain); + attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL); if (attr == NULL) { ret = LTTNG_ERR_FATAL; goto error; @@ -1214,7 +1216,7 @@ int cmd_enable_event(struct ltt_session *session, int domain, channel_name); if (uchan == NULL) { /* Create default channel */ - attr = channel_new_default_attr(domain); + attr = channel_new_default_attr(LTTNG_DOMAIN_UST); if (attr == NULL) { ret = LTTNG_ERR_FATAL; goto error; @@ -1235,7 +1237,7 @@ int cmd_enable_event(struct ltt_session *session, int domain, } /* At this point, the session and channel exist on the tracer */ - ret = event_ust_enable_tracepoint(usess, domain, uchan, event, filter); + ret = event_ust_enable_tracepoint(usess, uchan, event, filter); if (ret != LTTNG_OK) { goto error; } @@ -1261,8 +1263,8 @@ error: /* * Command LTTNG_ENABLE_ALL_EVENT processed by the client thread. */ -int cmd_enable_event_all(struct ltt_session *session, int domain, - char *channel_name, int event_type, +int cmd_enable_event_all(struct ltt_session *session, + struct lttng_domain *domain, char *channel_name, int event_type, struct lttng_filter_bytecode *filter, int wpipe) { int ret; @@ -1273,7 +1275,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain, rcu_read_lock(); - switch (domain) { + switch (domain->type) { case LTTNG_DOMAIN_KERNEL: { struct ltt_kernel_channel *kchan; @@ -1284,7 +1286,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain, session->kernel_session); if (kchan == NULL) { /* Create default channel */ - attr = channel_new_default_attr(domain); + attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL); if (attr == NULL) { ret = LTTNG_ERR_FATAL; goto error; @@ -1348,7 +1350,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain, channel_name); if (uchan == NULL) { /* Create default channel */ - attr = channel_new_default_attr(domain); + attr = channel_new_default_attr(LTTNG_DOMAIN_UST); if (attr == NULL) { ret = LTTNG_ERR_FATAL; goto error; @@ -1373,8 +1375,7 @@ int cmd_enable_event_all(struct ltt_session *session, int domain, switch (event_type) { case LTTNG_EVENT_ALL: case LTTNG_EVENT_TRACEPOINT: - ret = event_ust_enable_all_tracepoints(usess, domain, uchan, - filter); + ret = event_ust_enable_all_tracepoints(usess, uchan, filter); if (ret != LTTNG_OK) { goto error; } @@ -1634,44 +1635,20 @@ int cmd_set_consumer_uri(int domain, struct ltt_session *session, case LTTNG_DOMAIN_KERNEL: /* Code flow error if we don't have a kernel session here. */ assert(ksess); - - /* Create consumer output if none exists */ - consumer = ksess->tmp_consumer; - if (consumer == NULL) { - consumer = consumer_copy_output(ksess->consumer); - if (consumer == NULL) { - ret = LTTNG_ERR_FATAL; - goto error; - } - /* Trash the consumer subdir, we are about to set a new one. */ - memset(consumer->subdir, 0, sizeof(consumer->subdir)); - ksess->tmp_consumer = consumer; - } - + assert(ksess->consumer); + consumer = ksess->consumer; break; case LTTNG_DOMAIN_UST: /* Code flow error if we don't have a kernel session here. */ assert(usess); - - /* Create consumer output if none exists */ - consumer = usess->tmp_consumer; - if (consumer == NULL) { - consumer = consumer_copy_output(usess->consumer); - if (consumer == NULL) { - ret = LTTNG_ERR_FATAL; - goto error; - } - /* Trash the consumer subdir, we are about to set a new one. */ - memset(consumer->subdir, 0, sizeof(consumer->subdir)); - usess->tmp_consumer = consumer; - } - + assert(usess->consumer); + consumer = usess->consumer; break; } for (i = 0; i < nb_uri; i++) { ret = add_uri_to_consumer(consumer, &uris[i], domain, session->name); - if (ret < 0) { + if (ret != LTTNG_OK) { goto error; } } @@ -1695,6 +1672,12 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris, assert(name); + /* No URIs is not possible. */ + if (uris == NULL) { + ret = LTTNG_ERR_SESSION_FAIL; + goto session_error; + } + /* * Verify if the session already exist * @@ -1732,22 +1715,6 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris, goto consumer_error; } - /* - * This means that the lttng_create_session call was called with the _path_ - * argument set to NULL. - */ - if (uris == NULL) { - /* - * At this point, we'll skip the consumer URI setup and create a - * session with a NULL path which will flag the session to NOT spawn a - * consumer. - */ - DBG("Create session %s with NO uri, skipping consumer setup", name); - goto end; - } - - session->start_consumer = 1; - ret = cmd_set_consumer_uri(0, session, nb_uri, uris); if (ret != LTTNG_OK) { goto consumer_error; @@ -1755,7 +1722,6 @@ int cmd_create_session_uri(char *name, struct lttng_uri *uris, session->consumer->enabled = 1; -end: return LTTNG_OK; consumer_error: @@ -1960,6 +1926,7 @@ ssize_t cmd_list_domains(struct ltt_session *session, if (session->ust_session != NULL) { (*domains)[index].type = LTTNG_DOMAIN_UST; + (*domains)[index].buf_type = session->ust_session->buffer_type; index++; } @@ -2116,266 +2083,6 @@ void cmd_list_lttng_sessions(struct lttng_session *sessions, uid_t uid, } } -/* - * Command LTTNG_DISABLE_CONSUMER processed by the client thread. - */ -int cmd_disable_consumer(int domain, struct ltt_session *session) -{ - int ret; - struct ltt_kernel_session *ksess = session->kernel_session; - struct ltt_ust_session *usess = session->ust_session; - struct consumer_output *consumer; - - assert(session); - - if (session->enabled) { - /* Can't disable consumer on an already started session */ - ret = LTTNG_ERR_TRACE_ALREADY_STARTED; - goto error; - } - - if (!session->start_consumer) { - ret = LTTNG_ERR_NO_CONSUMER; - goto error; - } - - switch (domain) { - case 0: - DBG("Disable tracing session %s consumer", session->name); - consumer = session->consumer; - break; - case LTTNG_DOMAIN_KERNEL: - /* Code flow error if we don't have a kernel session here. */ - assert(ksess); - - DBG("Disabling kernel consumer"); - consumer = ksess->consumer; - - break; - case LTTNG_DOMAIN_UST: - /* Code flow error if we don't have a UST session here. */ - assert(usess); - - DBG("Disabling UST consumer"); - consumer = usess->consumer; - - break; - default: - ret = LTTNG_ERR_UNKNOWN_DOMAIN; - goto error; - } - - if (consumer) { - consumer->enabled = 0; - /* Success at this point */ - ret = LTTNG_OK; - } else { - ret = LTTNG_ERR_NO_CONSUMER; - } - -error: - return ret; -} - -/* - * Command LTTNG_ENABLE_CONSUMER processed by the client thread. - */ -int cmd_enable_consumer(int domain, struct ltt_session *session) -{ - int ret; - struct ltt_kernel_session *ksess = session->kernel_session; - struct ltt_ust_session *usess = session->ust_session; - struct consumer_output *consumer = NULL; - - assert(session); - - /* Can't enable consumer after session started. */ - if (session->enabled) { - ret = LTTNG_ERR_TRACE_ALREADY_STARTED; - goto error; - } - - switch (domain) { - case 0: - assert(session->consumer); - consumer = session->consumer; - break; - case LTTNG_DOMAIN_KERNEL: - /* Code flow error if we don't have a kernel session here. */ - assert(ksess); - - /* - * Check if we have already sent fds to the consumer. In that case, - * the enable-consumer command can't be used because a start trace - * had previously occured. - */ - if (ksess->consumer_fds_sent) { - ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL; - goto error; - } - - consumer = ksess->tmp_consumer; - if (consumer == NULL) { - ret = LTTNG_OK; - /* No temp. consumer output exists. Using the current one. */ - DBG3("No temporary consumer. Using default"); - consumer = ksess->consumer; - goto error; - } - - switch (consumer->type) { - case CONSUMER_DST_LOCAL: - DBG2("Consumer output is local. Creating directory(ies)"); - - /* Create directory(ies) */ - ret = run_as_mkdir_recursive(consumer->dst.trace_path, - S_IRWXU | S_IRWXG, session->uid, session->gid); - if (ret < 0) { - if (ret != -EEXIST) { - ERR("Trace directory creation error"); - ret = LTTNG_ERR_FATAL; - goto error; - } - } - break; - case CONSUMER_DST_NET: - DBG2("Consumer output is network. Validating URIs"); - /* Validate if we have both control and data path set. */ - if (!consumer->dst.net.control_isset) { - ret = LTTNG_ERR_URL_CTRL_MISS; - goto error; - } - - if (!consumer->dst.net.data_isset) { - ret = LTTNG_ERR_URL_DATA_MISS; - goto error; - } - - /* Check established network session state */ - if (session->net_handle == 0) { - ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL; - ERR("Session network handle is not set on enable-consumer"); - goto error; - } - - break; - } - - /* - * @session-lock - * This is race free for now since the session lock is acquired before - * ending up in this function. No other threads can access this kernel - * session without this lock hence freeing the consumer output object - * is valid. - */ - rcu_read_lock(); - /* Destroy current consumer. We are about to replace it */ - consumer_destroy_output(ksess->consumer); - rcu_read_unlock(); - ksess->consumer = consumer; - ksess->tmp_consumer = NULL; - - break; - case LTTNG_DOMAIN_UST: - /* Code flow error if we don't have a UST session here. */ - assert(usess); - - /* - * Check if we have already sent fds to the consumer. In that case, - * the enable-consumer command can't be used because a start trace - * had previously occured. - */ - if (usess->start_trace) { - ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL; - goto error; - } - - consumer = usess->tmp_consumer; - if (consumer == NULL) { - ret = LTTNG_OK; - /* No temp. consumer output exists. Using the current one. */ - DBG3("No temporary consumer. Using default"); - consumer = usess->consumer; - goto error; - } - - switch (consumer->type) { - case CONSUMER_DST_LOCAL: - DBG2("Consumer output is local. Creating directory(ies)"); - - /* Create directory(ies) */ - ret = run_as_mkdir_recursive(consumer->dst.trace_path, - S_IRWXU | S_IRWXG, session->uid, session->gid); - if (ret < 0) { - if (ret != -EEXIST) { - ERR("Trace directory creation error"); - ret = LTTNG_ERR_FATAL; - goto error; - } - } - break; - case CONSUMER_DST_NET: - DBG2("Consumer output is network. Validating URIs"); - /* Validate if we have both control and data path set. */ - if (!consumer->dst.net.control_isset) { - ret = LTTNG_ERR_URL_CTRL_MISS; - goto error; - } - - if (!consumer->dst.net.data_isset) { - ret = LTTNG_ERR_URL_DATA_MISS; - goto error; - } - - /* Check established network session state */ - if (session->net_handle == 0) { - ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL; - DBG2("Session network handle is not set on enable-consumer"); - goto error; - } - - if (consumer->net_seq_index == -1) { - ret = LTTNG_ERR_ENABLE_CONSUMER_FAIL; - DBG2("Network index is not set on the consumer"); - goto error; - } - - break; - } - - /* - * @session-lock - * This is race free for now since the session lock is acquired before - * ending up in this function. No other threads can access this kernel - * session without this lock hence freeing the consumer output object - * is valid. - */ - rcu_read_lock(); - /* Destroy current consumer. We are about to replace it */ - consumer_destroy_output(usess->consumer); - rcu_read_unlock(); - usess->consumer = consumer; - usess->tmp_consumer = NULL; - - break; - } - - session->start_consumer = 1; - - /* Enable it */ - if (consumer) { - consumer->enabled = 1; - /* Success at this point */ - ret = LTTNG_OK; - } else { - /* Should not really happend... */ - ret = LTTNG_ERR_NO_CONSUMER; - } - -error: - return ret; -} - /* * Command LTTNG_DATA_PENDING returning 0 if the data is NOT pending meaning * ready for trace analysis (or anykind of reader) or else 1 for pending data. @@ -2423,10 +2130,12 @@ error: void cmd_init(void) { /* - * Set network sequence index to 1 for streams to match a relayd socket on - * the consumer side. + * Set network sequence index to 1 for streams to match a relayd + * socket on the consumer side. */ - uatomic_set(&relayd_net_seq_idx, 1); + pthread_mutex_lock(&relayd_net_seq_idx_lock); + relayd_net_seq_idx = 1; + pthread_mutex_unlock(&relayd_net_seq_idx_lock); DBG("Command subsystem initialized"); }