/* * Bring up the server process if it is not already up. */ int nfs_callback_up(void) { struct svc_serv *serv = NULL; struct svc_sock *svsk; int ret = 0; lock_kernel(); mutex_lock(&nfs_callback_mutex); if (nfs_callback_info.users++ || nfs_callback_info.pid != 0) goto out; init_completion(&nfs_callback_info.started); init_completion(&nfs_callback_info.stopped); serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE); ret = -ENOMEM; if (!serv) goto out_err; /* FIXME: We don't want to register this socket with the portmapper */ ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport); if (ret < 0) goto out_err; if (!list_empty(&serv->sv_permsocks)) { svsk = list_entry(serv->sv_permsocks.next, struct svc_sock, sk_list); nfs_callback_tcpport = ntohs(inet_sk(svsk->sk_sk)->sport); dprintk ("Callback port = 0x%x\n", nfs_callback_tcpport); } else
static int make_socks(struct svc_serv *serv, int proto) { /* Make any sockets that are needed but not present. * If nlm_udpport or nlm_tcpport were set as module * options, make those sockets unconditionally */ static int warned; int err = 0; if (proto == IPPROTO_UDP || nlm_udpport) if (!find_socket(serv, IPPROTO_UDP)) err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport); if (err == 0 && (proto == IPPROTO_TCP || nlm_tcpport)) if (!find_socket(serv, IPPROTO_TCP)) err= svc_makesock(serv, IPPROTO_TCP, nlm_tcpport); if (!err) warned = 0; else if (warned++ == 0) printk(KERN_WARNING "lockd_up: makesock failed, error=%d\n", err); return err; }
/* * Make any sockets that are needed but not present. * If nlm_udpport or nlm_tcpport were set as module * options, make those sockets unconditionally */ static int make_socks(struct svc_serv *serv, int proto) { static int warned; int err = 0; if (proto == IPPROTO_UDP || nlm_udpport) if (!find_socket(serv, IPPROTO_UDP)) err = svc_makesock(serv, IPPROTO_UDP, nlm_udpport, SVC_SOCK_DEFAULTS); if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) if (!find_socket(serv, IPPROTO_TCP)) err = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport, SVC_SOCK_DEFAULTS); if (err >= 0) { warned = 0; err = 0; } else if (warned++ == 0) printk(KERN_WARNING "lockd_up: makesock failed, error=%d\n", err); return err; }
/* * Bring up the lockd process if it's not already up. */ int lockd_up(void) { static int warned; struct svc_serv * serv; int error = 0; down(&nlmsvc_sema); /* * Unconditionally increment the user count ... this is * the number of clients who _want_ a lockd process. */ nlmsvc_users++; /* * Check whether we're already up and running. */ if (nlmsvc_pid) goto out; /* * Sanity check: if there's no pid, * we should be the first user ... */ if (nlmsvc_users > 1) printk(KERN_WARNING "lockd_up: no pid, %d users??\n", nlmsvc_users); error = -ENOMEM; serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE); if (!serv) { printk(KERN_WARNING "lockd_up: create service failed\n"); goto out; } if ((error = svc_makesock(serv, IPPROTO_UDP, nlm_udpport)) < 0 #ifdef CONFIG_NFSD_TCP || (error = svc_makesock(serv, IPPROTO_TCP, nlm_tcpport)) < 0 #endif ) { if (warned++ == 0) printk(KERN_WARNING "lockd_up: makesock failed, error=%d\n", error); goto destroy_and_out; } warned = 0; /* * Create the kernel thread and wait for it to start. */ error = svc_create_thread(lockd, serv); if (error) { printk(KERN_WARNING "lockd_up: create thread failed, error=%d\n", error); goto destroy_and_out; } down(&lockd_start); /* * Note: svc_serv structures have an initial use count of 1, * so we exit through here on both success and failure. */ destroy_and_out: svc_destroy(serv); out: up(&nlmsvc_sema); return error; }
int nfsd_svc(unsigned short port, int nrservs) { int error; int none_left; struct list_head *victim; lock_kernel(); dprintk("nfsd: creating service\n"); error = -EINVAL; if (nrservs <= 0) nrservs = 0; if (nrservs > NFSD_MAXSERVS) nrservs = NFSD_MAXSERVS; /* Readahead param cache - will no-op if it already exists */ error = nfsd_racache_init(2*nrservs); nfs4_state_init(); if (error<0) goto out; if (!nfsd_serv) { atomic_set(&nfsd_busy, 0); error = -ENOMEM; nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); if (nfsd_serv == NULL) goto out; error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); if (error < 0) goto failure; #ifdef CONFIG_NFSD_TCP error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); if (error < 0) goto failure; #endif do_gettimeofday(&nfssvc_boot); /* record boot time */ } else nfsd_serv->sv_nrthreads++; nrservs -= (nfsd_serv->sv_nrthreads-1); while (nrservs > 0) { nrservs--; __module_get(THIS_MODULE); error = svc_create_thread(nfsd, nfsd_serv); if (error < 0) { module_put(THIS_MODULE); break; } } victim = nfsd_list.next; while (nrservs < 0 && victim != &nfsd_list) { struct nfsd_list *nl = list_entry(victim,struct nfsd_list, list); victim = victim->next; send_sig(SIG_NOCLEAN, nl->task, 1); nrservs++; } failure: none_left = (nfsd_serv->sv_nrthreads == 1); svc_destroy(nfsd_serv); /* Release server */ if (none_left) { nfsd_serv = NULL; nfsd_racache_shutdown(); nfs4_state_shutdown(); } out: unlock_kernel(); return error; }