To start off, I'm planning on building a component that handles file open/save requests for other components, primarily graphical applications. My plan is to use a qt5 QFileDialog for the user to select one or more files, then modify the vfs server's configuration to attach the selected file(s) to the component's filesystem.
To attach individual files to a component's filesystem, it seems like I should write a server-side link vfs plugin. The plugin would be like a symlink, but would transparently resolve the link within the vfs server, providing access to otherwise inaccessible files. Is this possible? If so, can you give me some tips on how to implement it?
Hi Ben,
On 07.06.2017 05:05, Nobody III wrote:
To start off, I'm planning on building a component that handles file open/save requests for other components, primarily graphical applications. My plan is to use a qt5 QFileDialog for the user to select one or more files, then modify the vfs server's configuration to attach the selected file(s) to the component's filesystem.
To attach individual files to a component's filesystem, it seems like I should write a server-side link vfs plugin. The plugin would be like a symlink, but would transparently resolve the link within the vfs server, providing access to otherwise inaccessible files. Is this possible? If so, can you give me some tips on how to implement it?
I like your idea but would pick a slightly different direction.
Let me illustrate the scenario that I would suggest:
------------------ | File picker (Qt) | ------------------ ^ | ----- ----------- ------------- | App | ---uses--> | fs filter | ---uses---> | file system | ----- ----------- -------------
The application (App) does not talk directly to a file-system server but has a file-system session to a filter component. To open a file, the app would generate an arbitrary file name 'a' and open the file 'a' at the filter. File 'a' does not actually exist though. The filter's job is to provide a virtual file 'a' such that read operations are redirected to a real file at the file system. In contrast to the app, the filter has access to the real file system. To determine the real file to be exposed to the app as 'a', the filter spawns a file-picker component as a child. When the file picker requests a file-system session from its parent (the filter), the filter hands out a read-only session to the real file system. Using this session, the file picker can present the file-system content via a QFileDialog. Once the user selects a file, the file picker informs the filter via a report submitted to a 'Report' session. Now, the filter knows that the virtual file 'a' corresponds to the selected real file and can forward read operations of the app to the real file system.
The case for writing would be similar.
This approach has the following interesting properties:
* The app does not need to know any name of the real files stored in the file system.
* The filter is transparent to existing applications that open a file given as argument. For example, mupdf would request always the same pdf. But thanks to the filter, it would open the pdf selected by the user. The real file name remains hidden.
* By separating the filter from the file picker, the complex Qt code does not need to be ultimately trusted. It has no write access to the file system. Even though it could read data, it has no way to leak it. In contrast, the filter has full read/write access to the file system. So it must be trusted. But in contrast to the file picker, its complexity is very low. Furthermore, the design in principle supports alternative implementations of the file picker without the need to modify the filter.
* The scenario does not need to reconfigure any components. In particular, there is no need for the file system to trust the filter. From the file system's perspective, the filter is just a regular client.
* The file picker could be killed each time after picking a file.
* If the app supports the selection of multiple files, it could open a directory instead of a file.
* The file name invented by the app may contain hints about the file types the app supports. This could be taken into account by the file picker (e.g., showing only PDF files if the app requested a file called 'a.pdf').
* The filter could remember the association of the virtual files with real files even after the app has closed a file. If the app saves a file with a name that was previously opened, it could open the already known real file instead of presenting a file picker. (thereby covering the distinction between the "save" vs. "save as" use cases)
Cheers Norman
I've started working on the implementation, and here's my plan: The component tree is the same as what you suggested, but fs_filter provides a "pipe" file to send requests (in XML format). The fs_filter component responds by spawning the Qt file picker. When the user chooses a file, the file is added to the filesystem provided by fs_filter, and fs_filter acknowledges the packet. The app can then read another file/pipe that contains the name of the selected file, then open the selected file.
While this approach is more complex, it allows for large sets of file types/extensions, which is useful for many larger applications (e.g. LibreOffice, Gimp). It also provides the name (but not the path) of the file chosen, which is useful when a user is working with several files, e.g. in a text editor. Hiding the name of the file may sound nice in theory, but seems to provide little real security benefit.
Essentially, my modifications should greatly increase usability, at the expense of a small amount of added complexity.
What are your thoughts? Any ideas for improvements?
Also, how do I spawn and use the file picker? Is there any existing example of using a child component like a library?
On Wed, Jun 7, 2017 at 9:46 AM, Norman Feske <norman.feske@...1...> wrote:
Hi Ben,
On 07.06.2017 05:05, Nobody III wrote:
To start off, I'm planning on building a component that handles file open/save requests for other components, primarily graphical applications. My plan is to use a qt5 QFileDialog for the user to select one or more files, then modify the vfs server's configuration to attach the selected file(s) to the component's filesystem.
To attach individual files to a component's filesystem, it seems like I should write a server-side link vfs plugin. The plugin would be like a symlink, but would transparently resolve the link within the vfs server, providing access to otherwise inaccessible files. Is this possible? If so, can you give me some tips on how to implement it?
I like your idea but would pick a slightly different direction.
Let me illustrate the scenario that I would suggest:
------------------ | File picker (Qt) | ------------------ ^ | ----- ----------- ------------- | App | ---uses--> | fs filter | ---uses---> | file system | ----- ----------- -------------
The application (App) does not talk directly to a file-system server but has a file-system session to a filter component. To open a file, the app would generate an arbitrary file name 'a' and open the file 'a' at the filter. File 'a' does not actually exist though. The filter's job is to provide a virtual file 'a' such that read operations are redirected to a real file at the file system. In contrast to the app, the filter has access to the real file system. To determine the real file to be exposed to the app as 'a', the filter spawns a file-picker component as a child. When the file picker requests a file-system session from its parent (the filter), the filter hands out a read-only session to the real file system. Using this session, the file picker can present the file-system content via a QFileDialog. Once the user selects a file, the file picker informs the filter via a report submitted to a 'Report' session. Now, the filter knows that the virtual file 'a' corresponds to the selected real file and can forward read operations of the app to the real file system.
The case for writing would be similar.
This approach has the following interesting properties:
The app does not need to know any name of the real files stored in the file system.
The filter is transparent to existing applications that open a file given as argument. For example, mupdf would request always the same pdf. But thanks to the filter, it would open the pdf selected by the user. The real file name remains hidden.
By separating the filter from the file picker, the complex Qt code does not need to be ultimately trusted. It has no write access to the file system. Even though it could read data, it has no way to leak it. In contrast, the filter has full read/write access to the file system. So it must be trusted. But in contrast to the file picker, its complexity is very low. Furthermore, the design in principle supports alternative implementations of the file picker without the need to modify the filter.
The scenario does not need to reconfigure any components. In particular, there is no need for the file system to trust the filter. From the file system's perspective, the filter is just a regular client.
The file picker could be killed each time after picking a file.
If the app supports the selection of multiple files, it could open a directory instead of a file.
The file name invented by the app may contain hints about the file types the app supports. This could be taken into account by the file picker (e.g., showing only PDF files if the app requested a file called 'a.pdf').
The filter could remember the association of the virtual files with real files even after the app has closed a file. If the app saves a file with a name that was previously opened, it could open the already known real file instead of presenting a file picker. (thereby covering the distinction between the "save" vs. "save as" use cases)
Cheers Norman
-- Dr.-Ing. Norman Feske Genode Labs
http://www.genode-labs.com · http://genode.org
Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Ben,
On 21.06.2017 05:45, Nobody III wrote:
I've started working on the implementation, and here's my plan: The component tree is the same as what you suggested, but fs_filter provides a "pipe" file to send requests (in XML format). The fs_filter component responds by spawning the Qt file picker. When the user chooses a file, the file is added to the filesystem provided by fs_filter, and fs_filter acknowledges the packet. The app can then read another file/pipe that contains the name of the selected file, then open the selected file.
this sacrifices the second advantage of my original suggestion, namely that the fs_filter is transparent to existing applications. With your approach, the application needs to speak an additional protocol (generating the requests to the "pipe").
In principle, the selection of multiple files could instead be handled by letting the fs_filter populate a virtual directory instead of providing a single file. But as I haven't thought this through, I don't want to keep you from exploring the direction you picked.
Also, how do I spawn and use the file picker? Is there any existing example of using a child component like a library?
Please have a look at gems/src/app/launcher, which hosts a number of components (e.g., menu_view) as child subsystems.
Cheers Norman
I've started picking up my fs_filter work again, but, particularly given the move away from individual filesystem servers toward VFS plugins, and the benefits (and partial implementation) of a dynamic VFS, I want to pursue that route (combined with a transparent link plugin) rather than the fs_filter component route.
In order to make the VFS sufficiently dynamic, it seems that the Dir_file_system code just needs more sophisticated code to handle config updates. Am I correct?
As for my VFS plugin, I need a way for it to access the rest of the VFS, particularly the root directory. As far as I can tell, this isn't possible with the current VFS code. How should we change this? It would allow my planned transparent link VFS plugin to work, as well as others such as copy-on-write union directories.
On Jun 27, 2017 1:02 AM, "Norman Feske" <norman.feske@...1...> wrote:
Hi Ben,
On 21.06.2017 05:45, Nobody III wrote:
I've started working on the implementation, and here's my plan: The component tree is the same as what you suggested, but fs_filter provides a "pipe" file to send requests (in XML format). The fs_filter component responds by spawning the Qt file picker. When the user chooses a file, the file is added to the filesystem provided by fs_filter, and fs_filter acknowledges the packet. The app can then read another file/pipe that contains the name of the selected file, then open the selected file.
this sacrifices the second advantage of my original suggestion, namely that the fs_filter is transparent to existing applications. With your approach, the application needs to speak an additional protocol (generating the requests to the "pipe").
In principle, the selection of multiple files could instead be handled by letting the fs_filter populate a virtual directory instead of providing a single file. But as I haven't thought this through, I don't want to keep you from exploring the direction you picked.
Also, how do I spawn and use the file picker? Is there any existing example of using a child component like a library?
Please have a look at gems/src/app/launcher, which hosts a number of components (e.g., menu_view) as child subsystems.
Cheers Norman
-- Dr.-Ing. Norman Feske Genode Labs
http://www.genode-labs.com · http://genode.org
Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
------------------------------------------------------------ ------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Ben,
On 11.02.2018 02:12, Nobody III wrote:
In order to make the VFS sufficiently dynamic, it seems that the Dir_file_system code just needs more sophisticated code to handle config updates. Am I correct?
Yes.
As for my VFS plugin, I need a way for it to access the rest of the VFS, particularly the root directory. As far as I can tell, this isn't possible with the current VFS code. How should we change this? It would allow my planned transparent link VFS plugin to work, as well as others such as copy-on-write union directories.
You are spot-on! We definitely need to pass the root directory to VFS plugins. Actually, I also desperately need this feature. :-)
However, right now, we deliberately postpone the addition of new VFS features as we first need to fully nurture the code that we already have. A look at the issue tracker [1] reveals the construction sites that should be wrapped up first.
[1] https://github.com/genodelabs/genode/search?q=vfs&state=open&type=Is...
Cheers Norman
Given that we have recently finished a release, and have a few months before the next release, now seems like a good time to add root directory passing to the VFS. I may be a bit impatient here, but I'm hesitant to be the one to make any API changes. That being said, I could go ahead and make the change if you won't get around to it soon. If that is the case, how important is backward compatibility here?
On Mon, Feb 12, 2018 at 12:13 PM, Norman Feske <norman.feske@...1...
wrote:
Hi Ben,
On 11.02.2018 02:12, Nobody III wrote:
In order to make the VFS sufficiently dynamic, it seems that the Dir_file_system code just needs more sophisticated code to handle config updates. Am I correct?
Yes.
As for my VFS plugin, I need a way for it to access the rest of the VFS, particularly the root directory. As far as I can tell, this isn't possible with the current VFS code. How should we change this? It would allow my planned transparent link VFS plugin to work, as well as others such as copy-on-write union directories.
You are spot-on! We definitely need to pass the root directory to VFS plugins. Actually, I also desperately need this feature. :-)
However, right now, we deliberately postpone the addition of new VFS features as we first need to fully nurture the code that we already have. A look at the issue tracker [1] reveals the construction sites that should be wrapped up first.
[1] https://github.com/genodelabs/genode/search?q=vfs&state= open&type=Issues&utf8=%E2%9C%93
Cheers Norman
-- Dr.-Ing. Norman Feske Genode Labs
https://www.genode-labs.com · https://genode.org
Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Ben,
On 16.03.2018 09:38, Nobody III wrote:
... now seems like a good time to add root directory passing to the VFS. I may be a bit impatient here, but I'm hesitant to be the one to make any API changes. That being said, I could go ahead and make the change if you won't get around to it soon. If that is the case, how important is backward compatibility here?
please have a look at the corresponding issue and the cited commit (on my topic branch):
https://github.com/genodelabs/genode/issues/2701
Cheers Norman