Re: [Linuxptp-devel] Adding libpmc
On Thu, Apr 16, 2020 at 05:06:46PM +, Geva, Erez wrote: > Do you have another suggestion? >From a technical POV, I think that the pmc_common.c file does not provide you very much at all. It does not, IMHO, rise to the level of substance for a real shared library. So the very idea of libpmc seems not worth it to me. You could just copy the .c and .h files into your project and use them directly. For the linuxptp project, I made the decision early on for a strong process model using the management interface straight out of IEEE 1588. The separation into ptp4l, phc2sys, and pmc follows from using that model. There are pros and cons to every design choice, of course, and some things would have been easier with one giant blob encompassing the functionally of ptp4l and phc2sys, like handling changes in port state for example. The choice of license was also a conscious one from the very beginning of the project, and I still stand by that decision. I do believe this is part of the reason for the success of the project. It might be useful to have a general purpose PTP monitoring library under a more permissive license for use in applications, but I imagine a much more ambitious scope, including things like PTP network discovery, alarms, graphs, GUI dashboards, and so on. In fact, I hoped someone else would take up the monitoring topic, and so I kept pmc simple, as a minimal example program. In any case, if you or somebody would like to start such a project, I would be supportive. Heck, I might even contribute now and again... Thanks, Richard ___ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
Re: [Linuxptp-devel] Adding libpmc
> > While the Kernel is under GPL 2. > > The headers and system call are under exception, so user can use the > > Kernel with non GPL code. But any changes or addition to the kernel > > itself should be GPL 2. > > This is very different. The Linux kernel is supposed to run any kind of > programs under various licenses. Linux PTP is not a generic mechanism > intended to run other software. > > [Slightly off topic: Moreover, the kernel has a strict boundary (uAPI) > between its internals and the user space programs. It's so strictly defined > that it does not require LGPL but instead is covered by a GPL exception. That > is different to libraries. In fact, the kernel uAPI is more close to stuff > like RPC or REST API than to libraries.] I merely use the kernel as example that copywrites holders think of using their GPL software with non GPL software. LGPL is only one way common to libraries, but there are other approaches. > > The exception means that any code that is part of the LinuxPTP must be > > coverd by GPL. > > > > But user may embedded a library in their non GPL application and > > communicate with the ptp4l. > > > > Do you have another suggestion? > > Why can't those applications that use parts of linuxptp code be licensed > under GPL? That seems like a win for everybody. If I could write all of my software as GPL, I would not ask. Although I personally in favour, sometimes there are more constrains that are beyond me. I do not ask you copywrites holders to solve all of the licence constrains, just for more flexible with a library that is derive from the project. I was looking for a management interface to communicate with the ptp4l without implement PTP all over again. I only find future SNMP support, but SNMP is more suitable for NMS. I did not find any simple way to query the ptp4l for it's status without using the PMC tool. > Jiri Any advice is welcome, if I can add GPL code to improve, I will. Erez ___ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
Re: [Linuxptp-devel] Adding libpmc
On Thu, 16 Apr 2020 17:06:46 +, Geva, Erez wrote: > While the Kernel is under GPL 2. > The headers and system call are under exception, so user can use the > Kernel with non GPL code. But any changes or addition to the kernel > itself should be GPL 2. This is very different. The Linux kernel is supposed to run any kind of programs under various licenses. Linux PTP is not a generic mechanism intended to run other software. [Slightly off topic: Moreover, the kernel has a strict boundary (uAPI) between its internals and the user space programs. It's so strictly defined that it does not require LGPL but instead is covered by a GPL exception. That is different to libraries. In fact, the kernel uAPI is more close to stuff like RPC or REST API than to libraries.] > The exception means that any code that is part of the LinuxPTP must > be coverd by GPL. > > But user may embedded a library in their non GPL application and > communicate with the ptp4l. > > Do you have another suggestion? Why can't those applications that use parts of linuxptp code be licensed under GPL? That seems like a win for everybody. Jiri ___ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
Re: [Linuxptp-devel] Adding libpmc
My logic is the same one you find in Linux kernel and in other GNU projects. While the Kernel is under GPL 2. The headers and system call are under exception, so user can use the Kernel with non GPL code. But any changes or addition to the kernel itself should be GPL 2. The exception means that any code that is part of the LinuxPTP must be coverd by GPL. But user may embedded a library in their non GPL application and communicate with the ptp4l. Do you have another suggestion? Erez -Original Message- From: Richard Cochran Sent: Thursday, 16 April 2020 17:09 To: Geva, Erez (ext) (DI PA CI R 3) Cc: Red Hat, Inc., Jiri Benc ; Miroslav Lichvar ; Jacob Keller ; Delio Brignoli ; Jacob Keller ; Vedang Patel ; linuxptp-devel@lists.sourceforge.net Subject: Re: Adding libpmc On Thu, Apr 16, 2020 at 02:18:25PM +, Geva, Erez wrote: > I see that linux PTP is under GPL 2. > > I would like to ask your permission to allow using a libpmc library and > headers needed by it under LGPL 2. As one of the copyright holders, I do not agree to any change of license. Thanks, Richard ___ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
Re: [Linuxptp-devel] Adding libpmc
On Thu, Apr 16, 2020 at 02:18:25PM +, Geva, Erez wrote: > I see that linux PTP is under GPL 2. > > I would like to ask your permission to allow using a libpmc library and > headers needed by it under LGPL 2. As one of the copyright holders, I do not agree to any change of license. Thanks, Richard ___ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
Re: [Linuxptp-devel] Adding libpmc
Hi Erez, On Thu, 16 Apr 2020 14:18:25 +, Geva, Erez wrote: > I see that linux PTP is under GPL 2. > > I would like to ask your permission to allow using a libpmc library > and headers needed by it under LGPL 2. Could I ask you to provide more context, please? I contributed to the Linux PTP project with the understanding it is licensed under GPL; agreeing to provide my contribution under a different license is something that I don't take lightly. You may understand that it's difficult to do such important decision based solely on a request without explanation about what project this needs, under what license, who's going to develop it, etc. Please elaborate on your plans. > As you are the copywrite holders, we need your explicit consent. I very much appreciate that you are aware of the legal implications and that you're reaching to us. Thanks, Jiri ___ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel
Re: [Linuxptp-devel] Adding libpmc
Hi, I see that linux PTP is under GPL 2. I would like to ask your permission to allow using a libpmc library and headers needed by it under LGPL 2. As you are the copywrite holders, we need your explicit consent. Thanks Erez Geva From: Geva, Erez (ext) (DI PA CI R 3) Sent: Thursday, 9 April 2020 16:30 To: linuxptp-devel@lists.sourceforge.net Subject: Adding libpmc Hi, As I thought that libpmc could be nice for several application that need to communicate with the ptp4l. I decided to make a short test. First I patch the makefile to create the libpmc.so diff --git a/makefile b/makefile index a23945a..f5e12da 100644 --- a/makefile +++ b/makefile @@ -23,6 +23,7 @@ VER = -DVER=$(version) CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS) LDLIBS = -lm -lrt $(EXTRA_LDFLAGS) PRG= ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster +LIBS = libpmc.so FILTERS= filter.o mave.o mmedian.o SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o TRANSP = raw.o transport.o udp.o udp6.o uds.o @@ -46,7 +47,7 @@ sbindir = $(prefix)/sbin mandir = $(prefix)/man man8dir= $(mandir)/man8 -all: $(PRG) +all: $(PRG) $(LIBS) ptp4l: $(OBJ) @@ -56,6 +57,18 @@ nsm: config.o $(FILTERS) hash.o interface.o msg.o nsm.o phc.o print.o \ pmc: config.o hash.o interface.o msg.o phc.o pmc.o pmc_common.o print.o sk.o \ tlv.o $(TRANSP) util.o version.o +.libs: + @mkdir -p $@ +# Generic rule to compile for shared libraries +.libs/%.o: %.c | .libs + $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -DPIC -c $< -o $@ + +LIBPMC_OBJS:=$(foreach n,config.o hash.o interface.o msg.o phc.o \ + pmc_common.o print.o sk.o tlv.o $(TRANSP) util.o version.o,.libs/$n) + +libpmc.so: $(LIBPMC_OBJS) + $(CC) -shared $^ $(LDLIBS) -o $@ + phc2sys: clockadj.o clockcheck.o config.o hash.o interface.o msg.o \ phc.o phc2sys.o pmc_common.o print.o $(SERVOS) sk.o stats.o \ sysoff.o tlv.o $(TRANSP) util.o version.o @@ -83,7 +96,7 @@ install: $(PRG) done clean: - rm -f $(OBJECTS) $(DEPEND) $(PRG) + rm -f $(OBJECTS) $(DEPEND) $(PRG) $(LIBS) $(LIBPMC_OBJS) distclean: clean rm -f .version diff --git a/.gitignore b/.gitignore index 3dbcbfa..091fbf2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ /phc_ctl /snmp4lptp /timemaster +/libpmc.so +/.libs/ Than I create a simple application #include #include extern "C" { #include "linuxptp/ds.h" #include "linuxptp/fsm.h" #include "linuxptp/notification.h" #include "linuxptp/pmc_common.h" #include "linuxptp/print.h" #include "linuxptp/tlv.h" #include "linuxptp/uds.h" #include "linuxptp/util.h" #include "linuxptp/version.h" } class My_Pmc { private: bool init_done; struct config *cfg; struct pmc *pmc; bool parse(struct ptp_message *msg); bool get(int id); public: My_Pmc(const char *cfg_file, const char *uds_address, uint8_t boundary_hops); ~My_Pmc(); bool get_port_data_set(); bool get_time_status_np(); // from TLV_PORT_DATA_SET - PORT_DATA_SET int64_t peerMeanPathDelay; std::string portState; // from TLV_TIME_STATUS_NP - TIME_STATUS_NP int64_t master_offset; std::string gmIdentity; }; bool My_Pmc::parse(struct ptp_message *msg) { if (msg_type(msg) != MANAGEMENT) return false; int action = management_action(msg); if (action < GET || action > ACKNOWLEDGE) return false; if (msg_tlv_count(msg) != 1) return false; struct TLV *tlv = (struct TLV *)msg->management.suffix; if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS && tlv->type != TLV_MANAGEMENT) return false; struct management_tlv *mgt; mgt = (struct management_tlv *)msg->management.suffix; if (mgt->length == 2 && mgt->id != TLV_NULL_MANAGEMENT) return false; struct time_status_np *tsn; struct portDS *p; switch (mgt->id) { case TLV_PORT_DATA_SET: p = (struct portDS *)mgt->data; if (p->portState > PS_SLAVE) portState = "NONE"; else portState = ps_str[p->portState]; peerMeanPathDelay = p->peerMeanPathDelay >> 16; break; case TLV_TIME_STATUS_NP: tsn = (struct time_status_np *)mgt->data; master_offset = tsn->master_offset; gmIdentity = cid2str(>gmIdentity); break; } return true; } My_Pmc::My_Pmc(const char *cfg_file, const char *uds_address, uint8_t boundary_hops): init_done(false) { cfg = config_create(); if (cfg == nullptr) return; if (config_read(cfg_file, cfg)) return; if (config_set_string(cfg, "uds_address", uds_address)) return; if (config_set_int(cfg, "network_transport", TRANS_UDS)) return; char uds_local[MAX_IFNAME_SIZE + 1]; snprintf(uds_local, sizeof(uds_local), "/var/run/pmc.%d", getpid()); pmc = pmc_create(cfg, TRANS_UDS, uds_local, boundary_hops, config_get_int(cfg, nullptr, "domainNumber"),
[Linuxptp-devel] Adding libpmc
Hi, As I thought that libpmc could be nice for several application that need to communicate with the ptp4l. I decided to make a short test. First I patch the makefile to create the libpmc.so diff --git a/makefile b/makefile index a23945a..f5e12da 100644 --- a/makefile +++ b/makefile @@ -23,6 +23,7 @@ VER = -DVER=$(version) CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS) LDLIBS = -lm -lrt $(EXTRA_LDFLAGS) PRG= ptp4l hwstamp_ctl nsm phc2sys phc_ctl pmc timemaster +LIBS = libpmc.so FILTERS= filter.o mave.o mmedian.o SERVOS = linreg.o ntpshm.o nullf.o pi.o servo.o TRANSP = raw.o transport.o udp.o udp6.o uds.o @@ -46,7 +47,7 @@ sbindir = $(prefix)/sbin mandir = $(prefix)/man man8dir= $(mandir)/man8 -all: $(PRG) +all: $(PRG) $(LIBS) ptp4l: $(OBJ) @@ -56,6 +57,18 @@ nsm: config.o $(FILTERS) hash.o interface.o msg.o nsm.o phc.o print.o \ pmc: config.o hash.o interface.o msg.o phc.o pmc.o pmc_common.o print.o sk.o \ tlv.o $(TRANSP) util.o version.o +.libs: + @mkdir -p $@ +# Generic rule to compile for shared libraries +.libs/%.o: %.c | .libs + $(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -DPIC -c $< -o $@ + +LIBPMC_OBJS:=$(foreach n,config.o hash.o interface.o msg.o phc.o \ + pmc_common.o print.o sk.o tlv.o $(TRANSP) util.o version.o,.libs/$n) + +libpmc.so: $(LIBPMC_OBJS) + $(CC) -shared $^ $(LDLIBS) -o $@ + phc2sys: clockadj.o clockcheck.o config.o hash.o interface.o msg.o \ phc.o phc2sys.o pmc_common.o print.o $(SERVOS) sk.o stats.o \ sysoff.o tlv.o $(TRANSP) util.o version.o @@ -83,7 +96,7 @@ install: $(PRG) done clean: - rm -f $(OBJECTS) $(DEPEND) $(PRG) + rm -f $(OBJECTS) $(DEPEND) $(PRG) $(LIBS) $(LIBPMC_OBJS) distclean: clean rm -f .version diff --git a/.gitignore b/.gitignore index 3dbcbfa..091fbf2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ /phc_ctl /snmp4lptp /timemaster +/libpmc.so +/.libs/ Than I create a simple application #include #include extern "C" { #include "linuxptp/ds.h" #include "linuxptp/fsm.h" #include "linuxptp/notification.h" #include "linuxptp/pmc_common.h" #include "linuxptp/print.h" #include "linuxptp/tlv.h" #include "linuxptp/uds.h" #include "linuxptp/util.h" #include "linuxptp/version.h" } class My_Pmc { private: bool init_done; struct config *cfg; struct pmc *pmc; bool parse(struct ptp_message *msg); bool get(int id); public: My_Pmc(const char *cfg_file, const char *uds_address, uint8_t boundary_hops); ~My_Pmc(); bool get_port_data_set(); bool get_time_status_np(); // from TLV_PORT_DATA_SET - PORT_DATA_SET int64_t peerMeanPathDelay; std::string portState; // from TLV_TIME_STATUS_NP - TIME_STATUS_NP int64_t master_offset; std::string gmIdentity; }; bool My_Pmc::parse(struct ptp_message *msg) { if (msg_type(msg) != MANAGEMENT) return false; int action = management_action(msg); if (action < GET || action > ACKNOWLEDGE) return false; if (msg_tlv_count(msg) != 1) return false; struct TLV *tlv = (struct TLV *)msg->management.suffix; if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS && tlv->type != TLV_MANAGEMENT) return false; struct management_tlv *mgt; mgt = (struct management_tlv *)msg->management.suffix; if (mgt->length == 2 && mgt->id != TLV_NULL_MANAGEMENT) return false; struct time_status_np *tsn; struct portDS *p; switch (mgt->id) { case TLV_PORT_DATA_SET: p = (struct portDS *)mgt->data; if (p->portState > PS_SLAVE) portState = "NONE"; else portState = ps_str[p->portState]; peerMeanPathDelay = p->peerMeanPathDelay >> 16; break; case TLV_TIME_STATUS_NP: tsn = (struct time_status_np *)mgt->data; master_offset = tsn->master_offset; gmIdentity = cid2str(>gmIdentity); break; } return true; } My_Pmc::My_Pmc(const char *cfg_file, const char *uds_address, uint8_t boundary_hops): init_done(false) { cfg = config_create(); if (cfg == nullptr) return; if (config_read(cfg_file, cfg)) return; if (config_set_string(cfg, "uds_address", uds_address)) return; if (config_set_int(cfg, "network_transport", TRANS_UDS)) return; char uds_local[MAX_IFNAME_SIZE + 1]; snprintf(uds_local, sizeof(uds_local), "/var/run/pmc.%d", getpid()); pmc = pmc_create(cfg, TRANS_UDS, uds_local, boundary_hops, config_get_int(cfg, nullptr, "domainNumber"), config_get_int(cfg, nullptr, "transportSpecific") << 4, 0); if (pmc != nullptr) init_done = true; } bool My_Pmc::get(int id) { if (!init_done) return false; if (pmc_send_get_action(pmc, id)) return false; struct pollfd pd; pd.fd = pmc_get_transport_fd(pmc); pd.events = POLLIN | POLLPRI; int cnt = poll(, 1, 200); // 200